我对Swift中有关var的使用和关键字{get set}的协议有疑问.
来自Apple文档:
如果协议要求属性可获取和可设置,则不能通过常量存储属性或只读计算属性来满足该属性要求.如果协议只要求属性可以获取,那么任何类型的属性都可以满足要求,如果这对您自己的代码有用,则该属性也可以设置.
属性要求始终声明为变量属性,前缀为var关键字.Gettable和settable属性通过在类型声明后写入{get set}来指示,并且通过编写{get}来指示gettable属性.
我无法理解为什么我不能使用let.只有get的协议中的var不只是一个let?
像这样的东西:
protocol someProtocol { var someProperty: String { get } }
它不会只是:
protocol someProtocol { let someProperty: String }
我错过了什么?
"只有get的协议中的var不只是一个let?" A号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"
该协议规定了哪些符合类显示到外-类型的某些属性String
命名someProperty
,你可以至少获得.
如果协议指定{ 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 }
这是完全允许的!