繁体   English   中英

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

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

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

来自Apple 文档

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

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

我不明白为什么我不能使用let 只有get的协议中的var不只是let吗?

像这样:

protocol someProtocol 
{
   var someProperty: String { get }
}

它不仅仅是:

protocol someProtocol 
{
   let someProperty: String
}

我错过了什么?

“只有 get 的协议中的 var 不只是 let 吗?” 不。 let表示一个常量。 但这里不是这种情况。 考虑以下:

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"

该协议指定了符合类向外部显示的内容 - 一些名为somePropertyString类型的属性,您至少可以获得。

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

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

区别在于

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
}

这是完全允许的!

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

protocol MyProtocol {
    var trythis: Int { get }
}

struct MyStructure: MyProtocol {
    let trythis: Int
}

let声明的属性在后台被认为是read-only 出于这个原因,协议可以通过将属性设置为只读来要求属性是常量。 可以使用一些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