如何符合协议的变量'集&得到?

时间:2016-11-26 17:15:15

标签: ios swift protocols getter-setter swift-protocols

我正在玩协议以及如何遵守它们。

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。它极大地解释了不同的场景。

2 个答案:

答案 0 :(得分:25)

来自Swift Reference

  

财产要求

     

...
   协议未指定属性是存储属性还是计算属性 - 它仅指定所需的属性名称和类型   ...
  属性要求始终声明为变量属性,前缀为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