ios 如何符合协议的变量设置和获取?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40820913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to conform to a protocol's variables' set & get?
提问by Honey
I'm playing around with protocols and how to conform to them.
我正在研究协议以及如何遵守它们。
protocol Human {
var height: Int {get set}
}
struct boy : Human {
var height: Int {return 5} // error!
}
I'm trying to learn different ways that I can implement set and get. However the code above throws the following error:
我正在尝试学习可以实现 set 和 get 的不同方法。但是上面的代码抛出以下错误:
type 'boy' does not conform to protocol 'Human'
“男孩”类型不符合“人类”协议
However writing as below won't have any errors:
但是写如下不会有任何错误:
struct boy : Human {
var height = 5 // no error
}
I don't understand the difference nor what exactly needs to be implemented when you can also seta variable. I looked into different questions and tutorials but they all just write and go without any deeper explanation.
当您还可以设置变量时,我不明白其中的区别,也不明白究竟需要实现什么。我研究了不同的问题和教程,但它们都只是写下来,没有任何更深入的解释。
EDIT:make sure you see Imanou's answer here. It greatly explains the different scenarios.
编辑:确保您在这里看到 Imanou 的回答。它极大地解释了不同的场景。
回答by Martin R
From the Swift Reference:
来自Swift 参考:
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 thevar
keyword. Gettable and settable properties are indicated by writing{ get set }
after their type declaration, and gettable properties are indicated by writing{ get }
.
属性要求
...
协议没有指定属性应该是存储属性还是计算属性——它只指定了所需的属性名称和类型。
...
属性要求始终声明为变量属性,以var
关键字为前缀。Gettable 和 settable 属性{ get set }
在它们的类型声明之后用写来表示,gettable 属性用写来表示{ get }
。
In your case
在你的情况下
var height: Int {return 5} // error!
is a computed propertywhich can only be get,it is a shortcut for
是一个只能得到的计算属性,它是一个快捷方式
var height: Int {
get {
return 5
}
}
But the Human
protocol requires a property which is gettable and settable.
You can either conform with a stored variableproperty (as you noticed):
但是该Human
协议需要一个可获取和可设置的属性。您可以符合存储的变量属性(如您所见):
struct Boy: Human {
var height = 5
}
or with a computed property which has both getter and setter:
或具有同时具有 getter 和 setter的计算属性:
struct Boy: Human {
var height: Int {
get {
return 5
}
set(newValue) {
// ... do whatever is appropriate ...
}
}
}
回答by Honey
Prerequisite:
先决条件:
Go into your playground and just write the snippet below:
进入你的操场,写下下面的代码片段:
var height: Int {
get {
return 5
}
}
or similarly:
或类似:
var height: Int {
return 5
}
Try to print height
's value, obviously works. So far so good
尝试打印height
的值,显然有效。到现在为止还挺好
print(height) // prints 5
However if you try to setit to a new value then you'll get an error:
但是,如果您尝试将其设置为新值,则会出现错误:
height = 8 // ERROR
error: cannot assign to value: 'height' is a get-only property
错误:无法分配给值:“高度”是一个只能获取的属性
Answer:
回答:
Based on Martin's answer, I first wrote:
根据马丁的回答,我首先写道:
set(newValue) {
height = newValue
}
Which put a ton of load on my memory and led me to thisquestion. Please take a look. So then I was figuring out what to write, and I kind of understood that if you don't want to do anything special you shouldn'tbe using computed properties and instead you should just use normal stored properties.
这给我的记忆带来了沉重的负担,并让我想到了这个问题。请看一下。然后我想知道要写什么,我有点明白如果你不想做任何特别的事情,你不应该使用计算属性,而应该只使用普通的存储属性。
So I wrote a similarcode
所以我写了一个类似的代码
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
Pro tip: When should you should make your properties read-only?
专业提示:什么时候应该将属性设为只读?
Normally if you make a property to be read-only ie { get }
it's because those properties are computedand you don't want the object to have control over it.
通常,如果您将属性设置为只读,即{ get }
这是因为这些属性是计算出来的,并且您不希望对象控制它。
Example you have a JSON object. It has multiple big objects like:
例如,您有一个 JSON 对象。它有多个大对象,如:
JSONData
- userInfo (name, address, age)
- devices (iPads, iPhones, Mac books)
- credentials (basic iCloud, pro iCloud, celebrity)
by making the role a read-only you're only allowing the server to tell the code base the role of the user.
通过将角色设置为只读,您只允许服务器告诉代码库用户的角色。
protocol Credentials {
var role: String { get }
init(person: Person)
}
class Person {
var userInfo: String
var devices: [String]
var creds: Credentials {
Credentials(person: self)
}
init(userInfo: userInfo, devices: [String]) {
self.userInfo = userInfo
self.devices = devices
}
}