the5avage
(The5avage)
1
Hi,
I'm a bit confused by the behavior of the following code. Why is it ok to call mutatingProtocolFunction() on an object declared with let, but not mutatingExtensionFunction()?
protocol hasMutatingFunction {
mutating func mutatingProtocolFunction()
}
extension hasMutatingFunction {
mutating func mutatingExtensionFunction() {
mutatingProtocolFunction()
mutatingProtocolFunction()
}
}
class C : hasMutatingFunction {
var count: Int = 0
func increment() {
count += 1
}
func mutatingProtocolFunction() {
count += 5
}
}
let c = C()
c.increment() // works
c.mutatingProtocolFunction() // works
c.mutatingExtensionFunction() // error: cannot use mutating member on immutable value: 'countdown' is a 'let' constant
Jens
2
And there's an interesting related discussion here.
That is:
protocol HasMutatingFunction {
mutating func mutatingProtocolFunction()
init()
}
extension HasMutatingFunction {
mutating func mutatingExtensionFunction() {
mutatingProtocolFunction()
mutatingProtocolFunction()
self = Self.init() // <--- Note that this is OK here.
}
}
class C : HasMutatingFunction {
var count: Int = 0
required init() { }
func increment() { count += 1 }
func mutatingProtocolFunction() {
count += 5
// self = Self.init() // <--- But not here.
}
}
1 Like
the5avage
(The5avage)
3
Thanks for the links and explanation. How does stdlib's Sequence and IteratorProtocol solve this? next() is a mutating function, there are a lot of extensions (e.g. drop(while:)) and i can implement a custom Sequence with structs and classes...
I found this workaround. It's a bit awkward, but at least it works with structs and classes.
protocol hasMutatingFunction {
mutating func mutatingProtocolFunction()
}
extension hasMutatingFunction {
mutating func mutatingExtensionFunction() {
_mutatingExtensionFunction(this: &self)
}
}
extension hasMutatingFunction where Self: AnyObject {
func mutatingExtensionFunction() {
var this = self
_mutatingExtensionFunction(this: &this)
}
}
private func _mutatingExtensionFunction<T: hasMutatingFunction>(this: inout T) {
this.mutatingProtocolFunction()
this.mutatingProtocolFunction()
}