2016-11-26 10 views
3

Я играю с протоколами и как им соответствовать.Как вы можете согласовать набор переменных протокола & 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 'структура мальчик: Human { пусть высота = 5 // ошибка! } 'также приведет к ошибке. Причина упоминается в [this] (https://stackoverflow.com/questions/40820913/how-can-you-conform-protocol-variables-set-get/40820968?noredirect1_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 требуется свойство, которое можно получить и настроить. Вы можете либо соответствовать сохраненному переменной свойства (как вы заметили):

struct Boy: Human { 
    var height = 5 
} 

или с вычисленным имуществом, которое имеет как геттер и сеттер:

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

'var height = 5', как это соотносится с получением и установкой? – Honey

+1

@Honey: 'var' объявляет * переменную *, которая может быть установлена ​​и установлена. –

+1

@Honey: '{get 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