为什么我可以通过将其重新影响到变量引用来修改不可变对象?

时间:2017-04-19 11:06:08

标签: swift immutability

我有一个不可变的朋友对象,我在类函数中传递它并将其放入VAR变量中。 即使引用是不可变的,我也可以修改它,编译器也不会抱怨。

在以下代码中,如果我不改变:

let mutableFriend = entity

通过

var mutableFriend = entity

我得到了:

  

无法传递一个不可变的inout参数:'friend'是'let'常量

为什么可以这样做?

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)

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

4 个答案:

答案 0 :(得分:1)

如果使用let引用任何对象,则可以更改对象的属性,调用方法,但不能将不同的对象分配给该标识符。

答案 1 :(得分:1)

如果你想让Friend-object真正不可变,你可以创建一个可选的初始化器,并将Friend-class的所有属性设置为let-constants。

这样的事情:

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 = ""
}

它是一个属性/对象的let-declaration,声明它是一个常量。它的基础属性仍然是可变的(如果指定的话,即var')。

答案 2 :(得分:0)

如果您想阻止更改Friend的名称,只需将其设为

即可
private(set) var name: String

答案 3 :(得分:0)

这是inout参数可能出现的错误。当需要inout参数时,我们不能使用不可变的let值作为参数。

  •   

    这是有道理的。常量不能修改。