如何符合协议的变量'set&get?

Hon*_*ney 12 protocols getter-setter ios swift swift-protocols

我正在玩协议以及如何符合它们.

protocol Human {    
    var height: Int {get set}    
}

struct boy : Human { 
    var height: Int  {return 5} // error!
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试学习不同的方法来实现set和get.但是上面的代码会引发以下错误:

类型'男孩'不符合协议'人'

但是写下面的内容不会有任何错误:

struct boy : Human { 
    var height = 5 // no error
}
Run Code Online (Sandbox Code Playgroud)

当你也可以设置一个变量时,我不明白其中的区别,也不知道究竟需要实现什么.我查看了不同的问题和教程,但他们只是写作并没有任何更深入的解释.

编辑: 确保你在这里看到Imanou的答案.它极大地解释了不同的场景.

Mar*_*n R 30

来自Swift参考:

财产要求

...
协议未指定属性是存储属性还是计算属性 - 它仅指定所需的属性名称和类型.
...
属性要求始终声明为变量属性,前缀为var关键字.Gettable和可设置属性通过{ get set }在类型声明后写入来指示,并且可通过写入来指示gettable属性{ get }.

在你的情况下

var height: Int  {return 5} // error!
Run Code Online (Sandbox Code Playgroud)

是一个只能得到计算属性,它是一个快捷方式

var height: Int {
    get {
        return 5
    }
}
Run Code Online (Sandbox Code Playgroud)

但该Human协议需要一个可获取和可设置的属性.您可以符合存储的变量属性(如您所见):

struct Boy: Human { 
    var height = 5
}
Run Code Online (Sandbox Code Playgroud)

或者具有同时具有getter和setter的计算属性:

struct Boy: Human { 
    var height: Int {
        get {
            return 5
        }
        set(newValue) {
            // ... do whatever is appropriate ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Hon*_*ney 8

先决条件:

进入你的游乐场,然后写下面的片段:

var height: Int {
    get {
        return 5
    }
}    
Run Code Online (Sandbox Code Playgroud)

或类似的:

var height: Int {
    return 5
}    
Run Code Online (Sandbox Code Playgroud)

尝试打印height的价值,显然有效.到现在为止还挺好

print(height) // prints 5
Run Code Online (Sandbox Code Playgroud)

但是,如果您尝试将其设置为新值,那么您将收到错误:

height = 8 // ERROR  
Run Code Online (Sandbox Code Playgroud)

错误:无法赋值:'height'是get-only属性


回答:

根据马丁的回答,我首先写道:

set(newValue) {
    height = newValue 
}
Run Code Online (Sandbox Code Playgroud)

这给我的记忆带来了很多负担,并引发了我的这个问题.请看一下.所以,我正在弄清楚要写什么,我有点明白,如果你不想做任何特别的事情,你应该使用计算属性,而应该只使用普通的存储属性.

所以我写了一个类似的代码

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
Run Code Online (Sandbox Code Playgroud)