Swift协议的可变性

Swift协议的可变性,swift,struct,swift-protocols,Swift,Struct,Swift Protocols,我目前对协议中的可获取属性有点困惑。考虑这个例子: 礼宾员{ 变量名称:字符串{get} } 我希望name属性是只读的,但我发现您可以更改该值,而无需编译器抱怨: 结构驱动程序:Person{ 变量名称:String } var driver=驾驶员姓名:Ryan driver.name=已更改! 如果我们用let关键字定义驱动程序,编译器就会产生错误,但如果我理解正确,它与协议无关,因为常量结构在Swift中是不可变的 方法交互的行为与我预期的一样: extension Person {

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

礼宾员{ 变量名称:字符串{get} } 我希望name属性是只读的,但我发现您可以更改该值,而无需编译器抱怨:

结构驱动程序:Person{ 变量名称:String } var driver=驾驶员姓名:Ryan driver.name=已更改! 如果我们用let关键字定义驱动程序,编译器就会产生错误,但如果我理解正确,它与协议无关,因为常量结构在Swift中是不可变的

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

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

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

协议要求是

可以读取的变量名

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

在您直接在驱动程序类型中更改变量的代码中,不涉及协议

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

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

协议仅声明所需的接口,而不是一致类型的完整接口。您的一致性类型可以添加协议不要求的额外属性/方法

对于getter和setter也是如此。如果协议属性要求为get,这意味着一致类型必须为属性指定一个getter,但并不意味着它也不能为属性指定一个setter

然而,反过来也不行。如果协议将一个属性声明为{get set},那么该属性必须有一个可变的setter。

苹果对此解释得很好

吸气剂和setter要求可以通过多种方式由一致性类型来满足。如果属性声明同时包含get和set关键字,则一致性类型可以使用存储的变量属性或可读写的计算属性(即同时实现getter和setter的属性)来实现它。但是,该属性声明不能作为常量属性或只读计算属性实现。如果属性声明仅包含get关键字,则可以将其实现为任何类型的属性

协议定义了要实现的mimimal接口。协议人员要求实现类型具有至少可读的名为name的字符串属性。设置的能力是额外的功能,协议不会限制您。