协议扩展,变异功能
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
}
}
稍后我在我的代码中尝试调用此方法并收到错误消息:
"cannot use mutating member on immutable value:'self' is immutable"
代码如下:
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
我唯一能想到的是 'Self' 在这种情况下是一个协议,而不是 class。但是我必须缺少一些东西才能使这个概念起作用,一个由协议定义的方法的默认实现,该协议编辑也由相同协议定义的值。
感谢您的帮助和时间:)
如果您打算仅将协议用于 classes 那么您可以
它是一个 class 协议(并删除 mutating
关键字):
protocol ColorImpressionableProtocol : class {
// ...
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?)
}
然后
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
编译没有问题。
您在 class 中采用此协议,因此 self(引用类型)是不可变的。由于协议中声明的可变方法,编译器期望 self 是可变的。这就是您收到此错误的原因。
可能的解决方案是:
1) Implement a non mutating version of the method where the protocol
being adopted. ie: implement the method in adopting class instead as a
protocol extension.
class MyClass : ColorImpressionableProtocol {
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?){
lightAccentColor = impresion?.lightAccentColor
accentColor = impresion?.accentColor
darkAccentColor = impresion?.darkAccentColor
specialTextColor = impresion?.specialTextColor
}
}
2) Make the protocol as class only protocol. This way we can remove the mutating keyword. It's the easiest solution but it can be only used in class.
仅制定协议 class :
protocol MyProtocolName : AnyObject { }
OR
protocol MyProtocolName : class { }
3) Make sure only value types adopt this protocol.This may not be useful in
all scenarios.
Here就是这个案例的详细解释和解决方法
我正在使用 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
}
}
稍后我在我的代码中尝试调用此方法并收到错误消息:
"cannot use mutating member on immutable value:'self' is immutable"
代码如下:
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
我唯一能想到的是 'Self' 在这种情况下是一个协议,而不是 class。但是我必须缺少一些东西才能使这个概念起作用,一个由协议定义的方法的默认实现,该协议编辑也由相同协议定义的值。
感谢您的帮助和时间:)
如果您打算仅将协议用于 classes 那么您可以
它是一个 class 协议(并删除 mutating
关键字):
protocol ColorImpressionableProtocol : class {
// ...
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?)
}
然后
init(impresion: ColorImpressionableProtocol?){
super.init(nibName: nil, bundle: nil)
adoptColorsFromImpresion(impresion)
}
编译没有问题。
您在 class 中采用此协议,因此 self(引用类型)是不可变的。由于协议中声明的可变方法,编译器期望 self 是可变的。这就是您收到此错误的原因。
可能的解决方案是:
1) Implement a non mutating version of the method where the protocol being adopted. ie: implement the method in adopting class instead as a protocol extension.
class MyClass : ColorImpressionableProtocol {
func adoptColorsFromImpresion(impresion: ColorImpressionableProtocol?){
lightAccentColor = impresion?.lightAccentColor
accentColor = impresion?.accentColor
darkAccentColor = impresion?.darkAccentColor
specialTextColor = impresion?.specialTextColor
}
}
2) Make the protocol as class only protocol. This way we can remove the mutating keyword. It's the easiest solution but it can be only used in class.
仅制定协议 class :
protocol MyProtocolName : AnyObject { }
OR
protocol MyProtocolName : class { }
3) Make sure only value types adopt this protocol.This may not be useful in all scenarios.
Here就是这个案例的详细解释和解决方法