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}”时,本质上意味着它必须能够被读取并且必须能够被改变,这可以通过语法中的声明来完成。存储的财产?
谢谢!
答案 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
隐含有get
和set
,而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
不会工作,因为它不可能改变。它也不关心内部细节,因此只要具有必要的访问权限,使用计算属性,私有设置器等就可以了。