Swift: 无法为协议的 属性 赋值?
Swift: Failed to assign value to a property of protocol?
Class A 提供了一个字符串值。 Class B 内部有两个 A 类型的成员,并提供一个计算 属性 "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
}
var value: String {
get {
return v.value
}
set {
v.value = newValue
}
}
}
这段代码很简单而且有效。由于 A 和 B 都有一个成员 "value",我将其作为这样的协议:
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
至
var v = self.v
v.value = newValue
又能用了!
这是 Swift 的错误,还是 属性 协议的特殊问题?
您必须将协议定义为 class
协议:
protocol ValueProvider : class {
var value: String {get set}
}
然后
var value: String {
get { return v.value }
set { v.value = newValue }
}
按预期编译和工作(即将新值分配给
v1
引用的对象,如果 v1 != nil
,以及对象
否则由 v2
引用。
v
是 ValueProvider
类型的只读计算 属性。
通过将协议定义为 class 协议,编译器知道
v
是 引用类型 ,因此它的 v.value
属性 即使引用本身是常量也可以修改。
您的初始代码示例有效,因为 v
属性 有
类型 A
是引用类型。
你的解决方法
set {
var tmp = v1 ?? v2
tmp.value = newValue
}
之所以有效,是因为 变量 的(读写)属性可以设置在
任何大小写(值类型或引用类型)。
Class A 提供了一个字符串值。 Class B 内部有两个 A 类型的成员,并提供一个计算 属性 "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
}
var value: String {
get {
return v.value
}
set {
v.value = newValue
}
}
}
这段代码很简单而且有效。由于 A 和 B 都有一个成员 "value",我将其作为这样的协议:
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
至
var v = self.v
v.value = newValue
又能用了!
这是 Swift 的错误,还是 属性 协议的特殊问题?
您必须将协议定义为 class
协议:
protocol ValueProvider : class {
var value: String {get set}
}
然后
var value: String {
get { return v.value }
set { v.value = newValue }
}
按预期编译和工作(即将新值分配给
v1
引用的对象,如果 v1 != nil
,以及对象
否则由 v2
引用。
v
是 ValueProvider
类型的只读计算 属性。
通过将协议定义为 class 协议,编译器知道
v
是 引用类型 ,因此它的 v.value
属性 即使引用本身是常量也可以修改。
您的初始代码示例有效,因为 v
属性 有
类型 A
是引用类型。
你的解决方法
set {
var tmp = v1 ?? v2
tmp.value = newValue
}
之所以有效,是因为 变量 的(读写)属性可以设置在 任何大小写(值类型或引用类型)。