I would like my protocol to declare that there is a read/write property available. I have attempted it, but this does not work:
protocol EdibleThing {
var eaten: Bool { get set }
}
class Pickle: EdibleThing { var eaten = false }
class RusticGrapefruit: EdibleThing { var eaten = false }
class Jar {
let contents: [EdibleThing] = [Pickle(), RusticGrapefruit()]
var nextItem: EdibleThing {
return contents.last ?? Pickle() // Lazy pickle generation technology
}
func eat() {
let food = nextItem
food.eaten = true // (!) ERROR: Cannot assign to result of this expression
}
}
What am I doing wrong? I think I've declared that the protocol has a get/set var called eaten
, so why can't I set it?
The protocol might be implemented by either classes and structs - that prevents you from changing the internal status of an instance of a class or struct implementing that protocol using an immutable variable.
To fix the problem you have to either declare the
food
variable as mutable:or declare the
EdibleThing
protocol to be implementable by classes only:Note that this happens because
food
is a variable ofEdibleThing
type - the compiler doesn't know if the actual instance is a value or reference type, so it raises an error. If you make it a variable of a class type, like this:the compiler knows without any ambiguity that it's a reference type, and in that case it allows the assignment. But I guess that breaks your app logic... so consider it just as an example