86

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

苹果文档

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

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

我不明白为什么我不能使用let。协议中只有getvar不只是let吗?

像这样的东西:

protocol someProtocol 
{
   var someProperty: String { get }
}

这不仅仅是:

protocol someProtocol 
{
   let someProperty: String
}

我错过了什么?

4

4 回答 4

75

“协议中只有 get 的 var 不只是 let 吗?” No. 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在实现中使用,但也必须使其可设置。

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

于 2015-12-20T21:26:26.213 回答
50

区别在于

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. 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!

于 2015-12-20T21:27:27.583 回答
3

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.

protocol MyProtocol {
    var trythis: Int { get }
}

struct MyStructure: MyProtocol {
    let trythis: Int
}
于 2020-05-23T16:05:05.330 回答
1

A property declared with let is considered read-only under the hood. 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.

protocol SomeProtocol {
    var someTypeProperty: Int { get }
}

struct Foo: SomeProtocol {
    let someTypeProperty: Int
}
于 2021-05-29T13:22:41.723 回答