Swift 协议的可变性

Vla*_*kov 0 struct swift swift-protocols

我目前对协议中的 gettable 属性有点困惑。考虑这个例子:

protocol Person {
    var name: String { get }
}
Run Code Online (Sandbox Code Playgroud)

我希望该name属性是只读的,但我发现您可以在没有编译器投诉的情况下更改该值:

struct Driver: Person {
    var name: String
}

var driver = Driver(name: "Ryan")
driver.name = "Changed!"
Run Code Online (Sandbox Code Playgroud)

如果我们driverlet关键字定义,那么编译器会引发错误,但如果我理解正确,它与协议无关,因为常量结构在 Swift 中设计为不可变的。

方法交互的行为与我预期的一样:

extension Person {
    mutating func changeName(_ newName: String) {
        self.name = newName    // Error: 'name' is a get-only property
    }
}
Run Code Online (Sandbox Code Playgroud)

我是 Swift 的新手,提到的细微差别可能没有任何实际用途,但是这种行为让我问自己,我是否对结构的工作方式缺乏一些基本的了解。

vad*_*ian 5

协议要求是

一个name可以读取的变量

这并不意味着采用此协议的结构中的变量一定是只读的。

在您直接在Driver类型中更改变量的代码中,不涉及协议。

另一方面,如果您注释协议类型,则会得到预期的错误

var driver : Person = Driver(name: "Ryan")
driver.name = "Changed!" // Cannot assign to property: 'name' is a get-only property
Run Code Online (Sandbox Code Playgroud)