我正在玩协议以及如何遵守它们。
protocol Human {
var height: Int {get set}
}
struct boy : Human {
var height: Int {return 5} // error!
}
我试图学习不同的方法来实现set和get。 但是,上面的代码会引发以下错误:
键入' boy'不符合协议'人类'
但是,如下所示不会有任何错误:
struct boy : Human {
var height = 5 // no error
}
当您设置变量时,我不了解差异,也不了解究竟需要实施的内容。我查看了不同的问题和教程,但他们只是写作并没有任何更深入的解释。
修改 确保你看到Imanou的回答here。它极大地解释了不同的场景。
答案 0 :(得分:25)
财产要求
...
协议未指定属性是存储属性还是计算属性 - 它仅指定所需的属性名称和类型 ...
属性要求始终声明为变量属性,前缀为var
关键字。在类型声明后编写{ get set }
表示可获取和可设置的属性,并通过编写{ get }
来指示gettable属性。
在你的情况下
var height: Int {return 5} // error!
是一个计算属性,它只能是 get,它是一个
的快捷方式var height: Int {
get {
return 5
}
}
但Human
协议需要一个可获取且可设置的属性。
您可以符合存储的变量属性(如您所见):
struct Boy: Human {
var height = 5
}
或者具有 getter和setter的计算属性:
struct Boy: Human {
var height: Int {
get {
return 5
}
set(newValue) {
// ... do whatever is appropriate ...
}
}
}
答案 1 :(得分:6)
进入你的操场,然后写下面的片段:
var height: Int {
get {
return 5
}
}
或类似地:
var height: Int {
return 5
}
尝试打印height
的值,显然有效。到目前为止一切顺利
print(height) // prints 5
但是,如果您尝试将设置为新值,则会出现错误:
height = 8 // ERROR
错误:无法赋值:'height'是一个只用属性
根据马丁的回答,我先写道:
set(newValue) {
height = newValue
}
这给我的记忆带来了很多负担,并引发了我this的问题。请看一下。那么我就搞清楚要写什么,我有点明白,如果你不想做任何特别的事情,你不应该使用计算属性,而应该只使用普通的存储属性。
所以我写了一个类似的代码
protocol Human {
var height: Float {get set}
}
struct Boy: Human {
// inch
var USheight : Float
// cm
var height: Float {
get {
return 2.54 * USheight
}
set(newValue) {
USheight = newValue/2.54
}
}
}
// 5 ft person
var person = Boy(USheight: 60)
// interestingly the initializer is 'only' based on stored properties because they
// initialize computed properties.
// equals to 152cm person
print(person.height) // 152.4