私はプロトコルとその拡張とプロトコルに準拠したクラスを持っています。プロトコル拡張で `inout`を使用できますか?
今protocol WarAbilities {
var strength: Int { get set }
func attack(inout opponent: WarAbilities)
}
extension WarAbilities {
func attack(inout opponent: WarAbilities) {
opponent.strength -= 1
}
}
class Warrior: WarAbilities {
var strength: Int
init(strength: Int) {
self.strength = strength
}
}
私は2人の戦士が戦うようにしたい場合:
let thug1 = Warrior(strength: 10)
let thug2 = Warrior(strength: 30)
thug1.attack(&thug2)
私は、このエラーメッセージが出ます:
error: cannot pass immutable value of type 'WarAbilities' as inout argument
がmutating
を追加するには有望に見えた:
protocol WarAbilities {
var strength: Int { get set }
mutating func attack(inout opponent: WarAbilities)
}
extension WarAbilities {
mutating func attack(inout opponent: WarAbilities) {
opponent.strength -= 1
}
}
しかし、コンパイラは満足していないどちらかと私は新しいエラーメッセージが何を意味するのか理解できない:Warrior
以来
error: cannot pass immutable value as inout argument: implicit conversion from 'Warrior' to 'WarAbilities' requires a temporary
をWarAbilities
に準拠して、私はそれらの1が仕事だろうと思った - しかし、スウィフトは、この種のを持っていないように見えます。 ..共分散?私がここで何を話しているのか分からない。
私の間違いは?
"あなたの例では、あなたはパラメータを上書きしないので、inoutは必要ないことに注意してください。 "You're wronそれについてg。彼は引数として渡されたインスタンスのプロパティを変更しようとしています。 'inout'がなければ、これは構造体パラメータの場合にはできません。だからこそ私の答えでは、これを 'class'プロトコルにしているので、コンパイラはこれがstructのパラメータではないことを知っています。 – matt
@matt 'inout'は、構造体またはクラスであることを気にせず、定数であるかどうかを気にします。構造体を渡すことはまったく同じ方法で行います。クラスのみのプロトコルを使用すると、構造体の突然変異の根底にある問題が取り除かれます。しかし、それは 'inout'とは関係がありません。あなたは' inout'として渡された構造体を上書きすることは確かに許可されています。 – luk2302
@mattあなたのコメントをもう一度読んだ後、あなたは 'inout'の必要性について部分的に正しいことに同意する必要があります。だから私の答えの最初のマイナーな部分は間違っています、はい。幸いにも、それは残りの議論と推論を変えない。 – luk2302