Ios Swift:未能为协议的属性赋值?

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 }

类提供一个字符串值。类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
    }

    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
}