private(set) 引发“self”在结构中是不可变的

Tys*_*sac 7 access-control ios swift

我不知道是不是我太累了,但我认为还有更多。(我试了两杯咖啡,还是没能解决问题……)

我想让一个变量从外部只读,但可以通过方法写入。(所以就像在那个例子中一样,我可以确保 favoriteNumber 只是个位数。

(我不想让它成为计算属性并在 get {}, set{} 中这样做,因为在我的另一个项目中,我想根据与 set {} 的“newValue”不同的值来修改变量)

struct Person {

    var name: String
    private(set) var favoriteNumber: Int? // Should only be single-digit

    init(name: String, number: Int) {

        self.name = name

        // Make sure favorite number is single-digit
        guard number >= 0 && number < 10 else {
            self.favoriteNumber = nil
        }
        self.favoriteNumber = number
    }

    func changeFavoriteNumber(number: Int) {
        guard number >= 0 && number < 10 else { return }
        self.favoriteNumber = number
    }
}
Run Code Online (Sandbox Code Playgroud)

.

线

self.favoriteNumber = number 
Run Code Online (Sandbox Code Playgroud)

在函数中

changeFavoriteNumber(number:)
Run Code Online (Sandbox Code Playgroud)

引发错误

"Cannot assign to property: 'self' is immutable"
Run Code Online (Sandbox Code Playgroud)

并建议“标记方法'变异'以使'自我'可变”。但这不是我想要的,因为我不想修改 Person 类型的实例,而是一个可变变量...(var favoriteNumber)

应该以这种方式使用:

let frank = Person.init(name: "Frank", number: 9)
frank.changeFavoriteNumber(number: 8)
Run Code Online (Sandbox Code Playgroud)

我不知道这里发生了什么(即使现在喝了 3 杯咖啡:)

Nob*_*ica 5

结构是值类型,与类具有不同的语义。存储类实例的变量作为对内存中其他位置的实际对象的引用存储;这意味着您可以有两个变量指向同一个对象,并且您可以修改类的成员,无论引用它的变量是否可变。

结构体不同。存储 a 实例的变量struct直接存储结构的成员,而不是作为对其他地方的对象的引用。这意味着将 struct 传递给函数或另一个变量会创建它的副本,而修改 astruct直接修改存储它的变量。

因此,结构是不可变的,除非它存储在var. 改变结构的函数必须按照mutating编译器的建议进行声明,以便编译器可以强制仅在let结构上调用非变异函数。