为什么我不能在Swift中使用let in协议?


77

我对Swift中使用var关键字{get set}的协议有疑问。

Apple文档

如果协议要求某个属性是可获取和可设置的,则该常量要求不能通过常量存储属性或只读计算属性来满足。如果协议仅要求一个属性是可获取的,则该要求可以由任何种类的属性来满足,并且如果该属性对您自己的代码有用,那么也可以对该属性进行设置是有效的。

属性要求始终声明为变量属性,并以var关键字为前缀。通过在类型声明后写{get set}来表示可获取和可设置的属性,通过写{get}来表示可获取的属性。

我不明白为什么我不能使用let。一个变种中,只有一个协议获取不只是

像这样:

protocol someProtocol 
{
   var someProperty: String { get }
}

这不只是:

protocol someProtocol 
{
   let someProperty: String
}

我想念什么吗?


9
一个gettable属性仍然可以更改值-协议实现者总是可以返回不同的值,协议调用者根本无法设置它们。另一方面,让我们定义一个常数。只能设置一次,不能有其他值。
pvg

1
@pvg,您为什么不将其发布为答案?
Courteouselk

是的,这是正确的答案。
sunshinejr

5
@AntonBronnikov回答简单的问题通常会导致谁能键入最冗长,最不容易理解的内容。对于小事情,更容易评论。还有,懒。
pvg

@pvg,我明白你的意思。一个人应该请是对的。
Courteouselk

Answers:


63

“协议中只有get的var不仅仅是让吗?” 否。Alet表示常数。但这不是事实。考虑以下:

protocol SomeProtocol {
    var someProperty: String { get }
}

class SomeClass : SomeProtocol {

    var someProperty: String = ""

    func cla () {
        someProperty = "asd"
    }
}

let someInstance = SomeClass()

print(someInstance.someProperty) // outputs ""
someInstance.cla()
print(someInstance.someProperty) // outputs "asd"

该协议指定哪些符合类节目到外-类型的某些属性String命名someProperty,你可以至少获得。

如果协议指定,则{ get }您的班级可以选择通过进行遵循,let someProperty: String = ""但是它可以类似地选择通过上述代码进行遵循。另一方面,如果协议指定{ get set }您不能let在实现中使用,但也必须使其可设置。

协议不能简单地定义一个值必须是常量,也不应该定义一个常量,即,实现细节必须由实现它的类/结构来照顾(或决定)。


回顾起来是如此简单和明显,在协议中只允许使用函数(然后是属性),但是我总是喜欢询问并解决任何疑问。现在,{ get set }它的用法一如既往的清晰,再次感谢!
Massimo Polimeni 2015年

1
协议无法简单地定义一个值必须为常数,为什么也不可以呢?Apple为什么不提供更多的粒度并允许定义let和var属性?或者您是说苹果本可以选择我说的话,但是他们选择了在实施级别提供的灵活性
Honey

45

区别在于

protocol MyProtocol {
    let someProperty: String
}

这没有任何意义-协议不应该规定如何 someProperty定义/存储协议,而只是规定它可以作为属性使用。它可以是计算的或存储的属性,但这是由实现者决定的,而不是协议本身。

protocol MyProtocol {
    var someProperty: String { get }  // abstract interface
}

struct MyStruct: MyProtocol {
    let someProperty: String  // concrete implementation: stored property
}

struct OtherStruct: MyProtocol {
    let i: Int
    var someProperty: String { return "\(i)" }  // concrete implementation: computed property
}

这是完全允许的!


1
协议不应该规定如何someProperty定义/存储协议不是定义变量名称/类型/必须可设置吗?Apple为什么不提供更多的粒度并允许定义let和var属性?
亲爱的

2

我认为协议可以要求结构具有某些东西,但不能限制结构或对象的功能。那不应该阻止您执行代码中可能想要做的事情,例如var,在协议中使用a并let接受实现。

protocol MyProtocol {
    var trythis: Int { get }
}

struct MyStructure: MyProtocol {
    let trythis: Int
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.