2016-11-26 57 views
3

我正在玩弄協議以及如何遵守協議。如何符合協議變量的set&get?

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

struct boy : Human { 
    var height: Int {return 5} // error! 
} 

我想學習不同的方法,我可以實現設置和獲取。 但是上面的代碼引發以下錯誤:

type 'boy' does not conform to protocol 'Human'

但是寫如下不會有任何錯誤:

struct boy : Human { 
    var height = 5 // no error 
} 

我不理解上的差異,也正是需要被實施時什麼你也可以設置一個變量。我研究了不同的問題和教程,但他們都只是寫下去,沒有更深入的解釋。

+0

FWIW'結構男孩:人類{ 設高度= 5 //錯誤! '也會產生一個錯誤。原因在[this]中提及(Martin https://stackoverflow.com/questions/40820913/how-can-you-conform-protocol-variables-set-get/40820968?noredirect=1#comment85239656_40820968)。 *'var'聲明一個變量,'let'一個常量。作爲存儲屬性,第一個是讀/寫,第二個只讀* – Honey

回答

11

Swift Reference

Property Requirements

...
The protocol doesn’t specify whether the property should be a stored property or a computed property—it only specifies the required property name and type.
...
Property requirements are always declared as variable properties, prefixed with the var keyword. Gettable and settable properties are indicated by writing { get set } after their type declaration, and gettable properties are indicated by writing { get } .

在你的情況

var height: Int {return 5} // error! 

計算性能這隻能是得到,這是一個 快捷方式

var height: Int { 
    get { 
     return 5 
    } 
} 

但是Human協議需要一個可獲取和可設置的屬性。 您可以與存儲變量財產符合(如你注意到):

​​

或用具有getter和setter方法所計算的特性:

struct Boy: Human { 
    var height: Int { 
     get { 
      return 5 
     } 
     set(newValue) { 
      // ... do whatever is appropriate ... 
     } 
    } 
} 
+0

'var height = 5'這是如何符合get和set的? – Honey

+1

@Honey:'var'聲明瞭一個*變量*,它可以被設置和獲取。 –

+1

@Honey:協議中的{{set set}'指示一個* gettable和可設置的屬性*,如果這是一個存儲或計算的屬性,則無關緊要。我已經添加了一個鏈接到文檔。 –

3

先決條件:

進入您的遊樂場,並只寫下面的代碼片段:

var height: Int { 
    get { 
     return 5 
    } 
}  

現在,如果您嘗試打印height的值,它會起作用。到目前爲止好

print(height) // prints 5 

但是如果你試圖設置到一個新的價值,那麼你會得到一個錯誤:

height = 8 // ERROR 

error: cannot assign to value: 'height' is a get-only property


答:

根據馬丁的回答,我第一次寫道:

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