![](/img/trans.png)
[英]Calling protocol's mutating function generates "has no member 'functionName'" error
[英]Protocol Extension, Mutating Function
我正在使用 swift 2.0,我有一个协议和协议的扩展来创建方法的默认实现,代码如下:
protocol ColorImpressionableProtocol {
var lightAccentColor: UIColor? {get set}
var accentColor: UIColor? {get set}
var darkAccentColor: UIColor? {get set}
var specialTextColor: UIColor? {get set}
mutating func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?)
}
extension ColorImpressionableProtocol {
mutating func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?){
lightAccentColor = impresion?.lightAccentColor
accentColor = impresion?.accentColor
darkAccentColor = impresion?.darkAccentColor
specialTextColor = impresion?.specialTextColor
}
}
我稍后在我的代码中尝试调用此方法并收到一个错误消息:
“不能在不可变值上使用可变成员:'self' 是不可变的”
代码如下:
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
我唯一能想到的是,在这种情况下,'Self' 是一个协议,而不是一个类。 但是,我必须缺少一些东西才能使这个概念起作用,由协议定义的方法的默认实现,该方法编辑也由同一协议定义的值。
感谢您的帮助和时间:)
如果您打算仅将协议用于类,那么您可以将其设为类协议(并删除mutating
关键字):
protocol ColorImpressionableProtocol : class {
// ...
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?)
}
然后
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
编译没有问题。
您在类中采用此协议,因此 self(引用类型)是不可变的。 由于协议中声明的可变方法,编译器期望 self 是可变的。 这就是您收到此错误的原因。
可能的解决方案是:
1) 实现采用协议的方法的非变异版本。 即:实现采用类的方法,而不是作为协议扩展。
class MyClass : ColorImpressionableProtocol {
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?){
lightAccentColor = impresion?.lightAccentColor
accentColor = impresion?.accentColor
darkAccentColor = impresion?.darkAccentColor
specialTextColor = impresion?.specialTextColor
}
}
2) 使协议成为类唯一协议。 这样我们就可以删除mutating关键字。 这是最简单的解决方案,但只能在课堂上使用。
只制作协议类:
protocol MyProtocolName : AnyObject { }
OR
protocol MyProtocolName : class { }
3) 确保只有值类型采用此协议。这可能不适用于所有场景。
下面是这个案例的详细解释和解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.