Mikael
Mikael

Reputation: 2395

Why can I modify an immutable object by re-affect it into a variable reference?

I have an immutable friend object, I pass it in a class function and put it into a VAR variable. Even if the reference is immutable, I can modify it and the compiler doesn't complain.

In the following code, if I don't change:

let mutableFriend = entity

by

var mutableFriend = entity

I get a:

Cannot pass an immutable as inout argument: 'friend' is a 'let' constant

Why is it possible to do that?

class FriendParser {
  class func parse(json: JSON, into entity: Friend)
  {
    var mutableFriend = entity
    guard let _ = try? setupFriend(friend: &mutableFriend, json: json) else {
       log.error("big fail during parsing")
    }
  }
}

let friend = Friend()
let jsonData = Request.requestFriend()
FriendParser.parse(json: jsonData, into: friend)

with

fileprivate class func setupFriend(friend:inout Friend, json:JSON) throws {}

Upvotes: 1

Views: 355

Answers (4)

ullstrm
ullstrm

Reputation: 10160

If you want the Friend-object to be truly immutable, you can create an optional initializer, and set all properties of the Friend-class to let-constants.

Something like this:

class Friend {
    let name : String

    init?() {
        let someCondition = true
        guard someCondition else { return nil }
        name = "Name"
    }
}

if let friend = Friend() {
    //The row below gives this error: Cannot assign to property, 'name' is a 'let' constant
    //    friend.name = ""
}

It's the let-declaration of a property/object that declares it as a constant. It's underlying properties are still mutable (if specified as such, i.e. var's).

Upvotes: 1

Govind Prajapati
Govind Prajapati

Reputation: 957

Here is an error that may occur with inout arguments. We cannot use an immutable let value as an argument when an inout argument is needed.

  • This makes sense. A constant cannot be modified.

Upvotes: 0

Alistra
Alistra

Reputation: 5195

If you want to block changing name of a Friend just make it

private(set) var name: String

Upvotes: 0

ankit
ankit

Reputation: 3647

If you reference any object with a let, you can alter object's properties, call methods, but you can't assign a different object to that identifier.

Upvotes: 1

Related Questions