[解決済み] Swift で、1 つ以上のプロトコルに準拠した特定の型の変数を宣言するにはどうしたらいいですか?
質問
Swiftでは、以下のように宣言することで、明示的に変数の型を設定することができます。
var object: TYPE_NAME
さらに一歩進んで、複数のプロトコルに準拠した変数を宣言したい場合には
protocol
を宣言します。
var object: protocol<ProtocolOne,ProtocolTwo>//etc
1つ以上のプロトコルに準拠し、かつ特定の基底クラスの型を持つオブジェクトを宣言したい場合はどうすればよいでしょうか。Objective-Cではこのようになります。
NSSomething<ABCProtocolOne,ABCProtocolTwo> * object = ...;
Swiftではこのようになると思います。
var object: TYPE_NAME,ProtocolOne//etc
これにより、基本型の実装だけでなく、プロトコルで定義された追加インターフェースにも柔軟に対応できるようになりました。
私が見逃しているかもしれない、もっと明白な別の方法はありますか?
例
例として、私が
UITableViewCell
ファクトリーがあるとする。このファクトリーはあるプロトコルに適合したセルを返す役割を担っている。プロトコルに準拠したセルを返す汎用的な関数を簡単に設定することができる。
class CellFactory {
class func createCellForItem<T: UITableViewCell where T:MyProtocol >(item: SpecialItem,tableView: UITableView) -> T {
//etc
}
}
後ほど、型とプロトコルの両方を活用しながら、これらのセルをデキューしたいと思います。
var cell: MyProtocol = CellFactory.createCellForItem(somethingAtIndexPath) as UITableViewCell
テーブルビューのセルがプロトコルに準拠していないため、エラーが返されます...
セルを指定できるようにしたいのですが、セルは
UITableViewCell
に準拠し、かつ
MyProtocol
に適合していますか?
ジャスティフィケーション
もし、あなたが ファクトリーパターン をご存知の方は、特定のインターフェースを実装した特定のクラスのオブジェクトを返すことができるという文脈で理解できるかと思います。
私の例のように、時には、特定のオブジェクトに適用されたときに意味をなすインターフェースを定義したいことがあります。私の例のテーブルビューのセルは、そのような正当化の一つです。
提供された型は言及されたインターフェースに正確に適合しませんが、ファクトリーが返すオブジェクトは適合します。したがって、私はベースクラスの型と宣言されたプロトコルインターフェースの両方と対話する柔軟性を望みます。
どのように解決するのですか?
Swift 4 では、型のサブクラスであり、同時に 1 つ以上のプロトコルを実装する変数を宣言することができるようになりました。
var myVariable: MyClass & MyProtocol & MySecondProtocol
任意の変数を行うこと。
var myVariable: (MyClass & MyProtocol & MySecondProtocol)?
またはメソッドのパラメータとして
func shakeEm(controls: [UIControl & Shakeable]) {}
AppleがWWDC2017で発表した セッション402で Swiftで何が新しくなったか
<ブロッククオート次に、クラスとプロトコルの合成についてお話します。そこで、ここでは UI要素のためのシェイカーブルプロトコルを紹介しました。 のプロトコルを紹介しました。そして、先に進んで UIKitのクラスをいくつか拡張して、実際にこのシェイク機能を提供するようにしました。 機能を提供するために、UIKitのクラスを拡張しました。そして今度は、簡単そうなことを書いてみたいと思います。I ただ、シェイク可能なコントロールの束を受け取り、有効になっているコントロールをシェイクする関数を書きたいだけです。 シェイク可能なコントロールの束を受け取り、有効になっているものをシェイクして注意を喚起する関数を書きたいのです。 書きたいんだ。この配列にはどんな型を書けばいいのでしょうか?実は イライラするし、やっかいだ。そこで、UIコントロールを使おうとすることもできる。しかし このゲームでは、すべてのUIコントロールがシャカシャカできるわけではないんだ。シャカブルを試してみてもいいのですが すべてのシャカブルがUIコントロールになるわけではありません。そして、実は、Swift 3でこれを表現する良い方法は Swift 3でこれを表現する良い方法はありません。 Swift 4 では、任意の数のプロトコルでクラスを構成する概念が導入されています。 プロトコルの任意の数を持つクラスを構成するという概念を導入しています。
関連
-
制御が非ボイド関数の終了に達する
-
[解決済み] 純粋な」Swift で弱いプロトコル参照を作るには (@objc なしで) どうしたらいいですか?
-
[解決済み] テキストフィールドを移動する方法(次へボタン/完了ボタン)
-
[解決済み] SwiftでURLから画像を読み込む/ダウンロードする
-
[解決済み] iphoneアプリのベータテストはどのように行うのですか?
-
[解決済み] インポート vs #インポート - iOS 7
-
[解決済み] iOS 13でダークモードをオプトアウトすることは可能ですか?
-
[解決済み] swiftにおけるプロトコルの配列型および関数パラメータとしての使用法
-
[解決済み] プロトコルは自分自身に適合しない?
-
[解決済み] Objective-Cのプロトコルでプロパティを含むものはどう扱えばいいのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
dyld: ライブラリがロードされていません。エラーの解決
-
IOSラーニングノート「このクラスはxxxのキーバリューコーディングに対応していません」問題解決
-
[解決済み] カスタムオブジェクトを含むNSMutableArrayをソートするにはどうすればよいですか?
-
[解決済み] Xcode 7のエラーです。"Missing iOS Distribution signing identity for ..." (iOS配布用署名IDがありません)
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] Objective-Cでデリゲートを作成するにはどうしたらいいですか?
-
[解決済み] 奇妙な不要なXcodeログを隠す
-
[解決済み] フレームワークを使用したiOSアプリがデバイス上でクラッシュ、dyld: ライブラリがロードされない、Xcode 6 Beta
-
[解決済み] IBOutletsはARCのもとで強くなるべきか、弱くなるべきか?
-
[解決済み] UITextViewのマージン/パディングをなくす方法