无法分配给类型的不可变表达式...但使用协议

qwe*_*_so 1 protocols swift

我知道有很多问题都是这样开始的。但是,这是我的代码片段:

protocol AProt { var a:Int { get set } }
protocol BProt { var b:Int { get set } }
protocol CProt { var c:Int { get set } }
class A:AProt, CProt { var a = 1;  var c = 3 }
class B:BProt, CProt { var b = 2; var c = 30 }

var a = A()
var b = B()
var c = a as CProt // works
c.c = 123
a = c as! A
print (a.c)
(a as CProt).c = 999 // throws error
print (a.c)
Run Code Online (Sandbox Code Playgroud)

看看这个答案,它表明 使得(...as...)表达式不可变。但 ...

虽然(a as CProt).c = 999失败并显示上述错误消息,但解决方法有效var c = a as CProt。我认为这是简单的编译器错误,但我想知道这里是否可以做一些事情(例如添加秘密关键字)。

Rob*_*ier 5

这不是编译器错误。CProt可以是值类型。考虑这段代码:

protocol CProt { var c:Int { get set } }
struct A: CProt { var a = 1;  var c = 3 } // Note this is a struct
var a = A()  // It's mutable
let c = a as CProt  // But this one isn't
c.c = 999  // So no surprise this fails
Run Code Online (Sandbox Code Playgroud)

你希望这能起作用吗?它不应该,因为它c是一个不可变的结构。这与您在 中编写的内容相同(a as CProt).c = 999

问题是您希望CProt成为引用类型。如果您需要,请这样说:

protocol CProt:class { var c:Int { get set } } // Note the addition of :class
class A: CProt { var a = 1;  var c = 3 }
let a = A()
(a as CProt).c = 999 // Success
Run Code Online (Sandbox Code Playgroud)