swift: class-onlyプロトコルとsetter

以下の単純なプロトコルがあったとして、これをGenerics関数と組み合わせた時valの値を変更する関数を書くことは文法違反となる。

protocol P {
   var val:Int { get set }
}
func updateVal<T:P>(item:T, v:Int)
{
   item.val = v // 代入は違反
}

なぜならプロトコルはstructにも適用可能であり、structではプロパティの値を変更する関数がmutating属性を必要とするからである。

しかしPの中にmutating属性の関数を定義するのは恐らくうまくない。それをやると今度はclassがmutating関数を持てないので、構造体にしか適用できないプロトコルができてしまう。またsetter関数が特定のプロパティの変更に対応することを文法的に保証できないので、設計的にもエレガントとはいえないだろう。

値の代入が必要な場合、諦めるならstructである。class-onlyプロトコルならば代入を行う関数を書くことができる

protocol P:class {
   var val: Int { get set }
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です