在Swift中,在创建符合需要的协议的对象类型(例如类)时,您不必使用getter和setter吗?

时间:2018-02-09 18:30:37

标签: swift swift4

protocol UserType {
    var name: String { get }
    var age: Int { get set }


struct Person: UserType { 
    var name: String //<- why is this okay?
    var age: Int //<- why is this okay? dont we need a getter setter
}

let somePerson = Person(name: "Billy", age: 22)

为什么在上面的例子中,我们不使用get构造或设置age的构造和名称的get构造?是因为在协议中,当属性被称为“{get set}”时,本质上意味着它必须能够被读取并且必须能够被改变,这可以通过语法中的声明来完成。存储的财产?

谢谢!

2 个答案:

答案 0 :(得分:2)

protocol UserType {
    var name: String { get }
    var age: Int { get set }
}

要理解的重要一点是,{ get }{ get set }仅仅是符号。他们与&#34; getter和setter&#34;无关。它们仅仅是向编译器描述协议要求的方式。 (你可以说这种符号令人困惑或误导,但它是我们所拥有的,所以我们必须忍受它。)

所以,基本上,所有这些都是:

  • 采用者必须声明name String实例属性。

  • 采用者还必须声明age Int实例属性,并且该属性必须是可写的。

这就意味着什么。那么,你已经满足了你的采用者(人)的这些要求。您的代码是合法的。结束。

答案 1 :(得分:0)

首先要注意的一件事:除非另有说明,否则每个属性都有一个隐式的getter和setter 。例如一个简单的var age: Int隐含有getset,而let age: Int隐含有get。当您声明手动getter和setter时,您覆盖某些内容,而不是创建一些其他方式不存在的内容。

至于协议,用明确的术语来说:

var name: String { get }表示附加类型必须具有可以读取的签名name:String的属性,即AKA。 get

var age: Int { get set }表示附加类型必须包含签名为age:String的属性,可以读取,AKA get和{{1} }

请注意,这些规则包含而非独占。这些要求并不关心他们的满意程度,也不会拒绝其他任何事情。

这意味着在您的示例中,set的属性可以正常运行,因为它只需要访问权限,但let name: String 不会工作,因为它不可能改变。它也不关心内部细节,因此只要具有必要的访问权限,使用计算属性,私有设置器等就可以了。