简体   繁体   English

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

[英]Why I can't use let in protocol in Swift?

I have a doubt about protocols in Swift about the use of var and the keywords { get set } .我对 Swift 中关于var关键字 {get set}的使用的协议有疑问。

From Apple documentation :来自Apple 文档

If a protocol requires a property to be gettable and settable, that property requirement cannot be fulfilled by a constant stored property or a read-only computed property.如果协议要求属性是可获取和可设置的,则该属性要求不能通过常量存储属性或只读计算属性来满足。 If the protocol only requires a property to be gettable, the requirement can be satisfied by any kind of property, and it is valid for the property to be also settable if this is useful for your own code.如果协议只要求一个属性是可获取的,那么任何类型的属性都可以满足该要求,并且如果这对您自己的代码有用,那么属性也是可设置的也是有效的。

Property requirements are always declared as variable properties, prefixed with the var keyword.属性要求总是声明为变量属性,并以 var 关键字为前缀。 Gettable and settable properties are indicated by writing { get set } after their type declaration, and gettable properties are indicated by writing { get }.可获取和可设置属性通过在类型声明后写入 { get set } 来表示,而可获取属性通过写入 { get } 来表示。

I can't understand why I can't use let .我不明白为什么我不能使用let A var in a protocol with only get isn't just a let ?只有get的协议中的var不只是let吗?

Something like this:像这样:

protocol someProtocol 
{
   var someProperty: String { get }
}

it would not be just:它不仅仅是:

protocol someProtocol 
{
   let someProperty: String
}

I'm missing something?我错过了什么?

"A var in a protocol with only get isn't just a let?" “只有 get 的协议中的 var 不只是 let 吗?” No. A let indicates a constant.不。 let表示一个常量。 But that is not the case here.但这里不是这种情况。 Consider the following:考虑以下:

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"

The protocol specifies what the conforming class shows to the outside - some property of type String named someProperty which you can at least get.该协议指定了符合类向外部显示的内容 - 一些名为somePropertyString类型的属性,您至少可以获得。

If the protocol specifies { get } your class can choose to conform via let someProperty: String = "" but it can similarly choose to conform via the above code.如果协议指定{ get }您的类可以通过let someProperty: String = ""选择符合,但它也可以类似地通过上述代码选择符合。 If on the other hand the protocol specifies { get set } you cannot use let in the implementation but have to make it set-able as well.另一方面,如果协议指定了{ get set } ,则您不能在实现中使用let ,但也必须使其可设置。

A protocol simply cannot define that a value has to be constant - neither should it, that is an implementation detail that has to be taken care (or decided about) by the class / struct that implements it.协议不能简单地定义一个值必须是常量——也不应该,这是一个实现细节,必须由实现它的类/结构来处理(或决定)。

The difference is between区别在于

protocol MyProtocol {
    let someProperty: String
}

which makes no sense — a protocol isn't supposed to dictate how someProperty is defined/stored, only that it's available as a property.这是没有意义的——协议不应该规定someProperty如何定义/存储的,只是作为一个属性可用。 It could be either a computed or stored property, but that's for the implementer to decide, not the protocol itself.它可以是计算的或存储的属性,但这是由实现者决定的,而不是协议本身。

and

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
}

which is perfectly allowed!这是完全允许的!

I think a protocol can require that a structure has something, but it can't restrict functionality of struct or object.我认为一个协议可以要求一个结构有一些东西,但它不能限制结构或对象的功能。 That shouldn't prevent you from doing what you'd probably like to do in code, for example using a var in the protocol and a let for the implementation is acceptable.这不应该阻止您做您可能想在代码中做的事情,例如,在协议中使用var并在实现中使用let是可以接受的。

protocol MyProtocol {
    var trythis: Int { get }
}

struct MyStructure: MyProtocol {
    let trythis: Int
}

A property declared with let is considered read-only under the hood.let声明的属性在后台被认为是read-only For this reason, a protocol can require that a property be a constant by setting it read-only.出于这个原因,协议可以通过将属性设置为只读来要求属性是常量。 This deduction can be verified using some of the Objc runtime functions property_getAttributes .可以使用一些Objc运行时函数property_getAttributes来验证此推论。

protocol SomeProtocol {
    var someTypeProperty: Int { get }
}

struct Foo: SomeProtocol {
    let someTypeProperty: Int
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM