関係ありそうな、こんな記事がありました。
Protocol-Oriented Problems and the Immutable 'self' Error
引用1:
Swift
1enum Direction {
2 case None, Forward, Backward, Up, Down, Left, Right
3}
4
5protocol VehicleType {
6 var speed: Int { get set }
7 var direction: Direction { get }
8 mutating func changeDirectionTo(direction: Direction)
9 mutating func stop()
10}
11
12extension VehicleType {
13 mutating func stop() {
14 speed = 0
15 }
16}
17
18class Car: VehicleType {
19 var speed = 0
20 private(set) var direction: Direction = .None
21
22 func changeDirectionTo(direction: Direction) {
23 self.direction = direction
24
25 if direction == .None {
26 stop()
27 }
28 }
29}
引用2:
What does “Cannot use mutating member on immutable value: ‘self’ is immutable” mean?
Understanding the Error
There are three insights that help to clarify the error.
- Recall that the protocol VehicleType declares that stop() is a mutating method. We declared it like this because stop() changes the value of a property, speed, and we are required to mark it as mutating in case value types conform.
- VehicleType’s protocol extension provides a default implementation for stop().
- Car is a reference type.
引用3:
stop() is a mutating method, with a default implementation, that the compiler expects will change self. But Car is a reference type. That means the self—the reference to the Car instance that is used to call stop()—that is available within changeDirectionTo(_:) is immutable!
Thus, the compiler gives us an error because stop() wants to mutate self, but the self available within changeDirectionTo(_:) is not mutable.
引用4:
Three Solutions
There are three principal ways to solve this problem.
- Implement a non-mutating version of stop() on Car.
- Mark the VehicleType protocol as class only: protocol VehicleType: class { ... }.
- Make Car a struct.
Swiftの理解がまだ浅いため、解釈を間違えているかもしれませんが、今回の質問者さんのケースですと
- associatedObjectのセッターはオブジェクトの状態を変化させる、暗黙的mutatingメソッドと解釈される...mutatingメソッドは通常不変なstructのプロパティを書き換えることができ、selfまでも書き換えられるらしいので(新しいstructのインスタンスができて、それを参照するようになるということ?)、このセッターは潜在的にselfを書き換えうる?
- このプロパティに値をセットする時、暗黙の引数としてselfが渡される
- Swiftは(structは許すが)classであるAAAのself書き換えを許さないためエラーを出す
という状況なんでしょうか...?
とりあえず筆者の方の第2の解決案の、プロトコルをclass専用にする方法で
Swift
1protocol RepresentedObjectable : class {
2
3 associatedtype RepresentedObject
4
5 var associatedObject: RepresentedObject? { get set }
6}
としてみるとどうでしょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/11 11:24