Ios Swift:未能为协议的属性赋值?
类提供一个字符串值。类B在其内部有两个类型的成员,并提供一个计算属性“v”来选择其中一个Ios Swift:未能为协议的属性赋值?,ios,swift,properties,swift-protocols,Ios,Swift,Properties,Swift Protocols,类提供一个字符串值。类B在其内部有两个类型的成员,并提供一个计算属性“v”来选择其中一个 class A { var value: String init(value: String) { self.value = value } } class B { var v1: A? var v2: A = A(value: "2") private var v: A { return v1 ?? v2 }
class A {
var value: String
init(value: String) {
self.value = value
}
}
class B {
var v1: A?
var v2: A = A(value: "2")
private var v: A {
return v1 ?? v2
}
var value: String {
get {
return v.value
}
set {
v.value = newValue
}
}
}
这段代码很简单,很有效。由于A和B都有一个成员“值”,我将其作为一个协议,如下所示:
protocol ValueProvider {
var value: String {get set}
}
class A: ValueProvider {
var value: String
init(value: String) {
self.value = value
}
}
class B: ValueProvider {
var v1: ValueProvider?
var v2: ValueProvider = A(value: "2")
private var v: ValueProvider {
return v1 ?? v2
}
var value: String {
get {
return v.value
}
set {
v.value = newValue // Error: Cannot assign to the result of the expression
}
}
}
如果我更改以下代码
v.value = newValue
到
它又起作用了
这是Swift的错误,还是协议属性的特殊问题?您必须将协议定义为
类
协议:
protocol ValueProvider : class {
var value: String {get set}
}
然后
按预期编译和工作(即将新值分配给
由v1
引用的对象,如果v1!=nil
,则指向该对象
被v2
引用,否则)
v
是类型为ValueProvider
的只读计算属性。
通过将协议定义为类协议,编译器知道
v
是一种参考类型,因此它的v.value
即使引用本身是常量,也可以修改属性
您最初的代码示例之所以有效,是因为有v
属性
类型A
,它是一种参考类型
还有你的变通方法
set {
var tmp = v1 ?? v2
tmp.value = newValue
}
因为变量的(读写)属性可以在
任何情况(值类型或引用类型)
var value: String {
get { return v.value }
set { v.value = newValue }
}
set {
var tmp = v1 ?? v2
tmp.value = newValue
}