オブジェクトが「オン」状態か「オフ」状態かを示す簡単なプロトコルを作成しようとしています。それが何であるかの解釈は、実装するオブジェクトによって異なります。の場合UISwitch
、それはスイッチがオンかオフかです (当然)。の場合UIButton
、それはボタンがselected
状態にあるかどうかである可能性があります。の場合Car
、それは車のエンジンがオンになっているかどうか、または動いているかどうかである可能性があります。そこで、この単純なプロトコルの作成に着手しました。
protocol OnOffRepresentable {
func isInOnState() -> Bool
func isInOffState() -> Bool
}
これで、前述の UI コントロールを次のように拡張できます。
extension UISwitch: OnOffRepresentable {
func isInOnState() -> Bool { return on }
func isInOffState() -> Bool { return !on }
}
extension UIButton: OnOffRepresentable {
func isInOnState() -> Bool { return selected }
func isInOffState() -> Bool { return !selected }
}
これで、これらの種類のオブジェクトの配列を作成し、それをループして、それらがオンかオフかを確認できます。
let booleanControls: [OnOffRepresentable] = [UISwitch(), UIButton()]
booleanControls.forEach { print($0.isInOnState()) }
すごい!次に、これらのコントロールを にマップするディクショナリを作成してUILabel
、コントロールの状態が変化したときにコントロールに関連付けられたラベルのテキストを変更できるようにします。だから私は自分の辞書を宣言します:
var toggleToLabelMapper: [OnOffRepresentable : UILabel] = [:]
// error: type 'OnOffRepresentable' does not conform to protocol 'Hashable'
おー!右!愚かな私。それでは、プロトコル構成を使用してプロトコルを更新しましょう (結局のところ、ここで使用したいコントロールはすべて Hashable です: UISwitch、UIButton など):
protocol OnOffRepresentable: Hashable {
func isInOnState() -> Bool
func isInOffState() -> Bool
}
しかし今、私は新しいエラーのセットを取得します:
error: protocol 'OnOffRepresentable' can only be used as a generic constraint because it has Self or associated type requirements
error: using 'OnOffRepresentable' as a concrete type conforming to protocol 'Hashable' is not supported
わかりました...スタックオーバーフローの掘り出しと検索を行います。Set and protocols in Swift、Using some protocol as a specific type conforming to another protocol is not supportedなど、有望と思われる多くの記事を見つけtype erasure
ました。 : http://krakendev.io/blog/generic-protocols-and-their-shortcomings、http://robnapier.net/erasure、およびhttps://realm.io/news/type-erased-wrappers-in-迅速/ほんの数例を挙げると。
これは私が立ち往生するところです。私はこれらすべてを読んでみました。Hashable
また、プロトコルに準拠するクラスを作成しようとしましたOnOffRepresentable
が、すべてを接続する方法がわかりません。