[解決済み] プロトコルは、SelfまたはassociatedTypeの要件を持つため、一般的な制約としてのみ使用できる
質問
RequestTypeというプロトコルがあり、以下のようなassociatedTypeモデルを持っています。
public protocol RequestType: class {
associatedtype Model
var path: String { get set }
}
public extension RequestType {
public func executeRequest(completionHandler: Result<Model, NSError> -> Void) {
request.response(rootKeyPath: rootKeyPath) { [weak self] (response: Response<Model, NSError>) -> Void in
completionHandler(response.result)
guard let weakSelf = self else { return }
if weakSelf.logging { debugPrint(response) }
}
}
}
今度は、失敗したすべてのリクエストのキューを作ろうとしています。
public class RequestEventuallyQueue {
static let requestEventuallyQueue = RequestEventuallyQueue()
let queue = [RequestType]()
}
しかし、次の行でエラーが発生します。
let queue = [RequestType]()
は、プロトコルRequestTypeはSelfまたはassociatedTypeの要件を持つため、ジェネリック制約としてのみ使用できる、というエラーが発生します。
どのように解決するのですか?
とりあえず、プロトコルを調整して、関連する型を使用するルーチンを追加したとします。
public protocol RequestType: class {
associatedtype Model
var path: String { get set }
func frobulateModel(aModel: Model)
}
そして、Swift では、配列として
RequestType
を好きなように作成できるようになったとします。 それらのリクエストタイプの配列を関数に渡すことができました。
func handleQueueOfRequests(queue: [RequestType]) {
// frobulate All The Things!
for request in queue {
request.frobulateModel(/* What do I put here? */)
}
}
全部をフロブル化したいというところまではわかったのですが、呼び出しに渡す引数の種類を知る必要があります。 私のいくつかの
RequestType
エンティティは
LegoModel
を取るものもあれば
PlasticModel
を取ることもできますし、他の人は
PeanutButterAndPeepsModel
. Swift はこの曖昧さに不満なので、関連する型があるプロトコルの変数を宣言させません。
同時に、それは例えば、配列を作成することは完全に理にかなっています
RequestType
の配列を作成することは非常に理にかなっています。
LegoModel
. これは合理的に見えますし、実際そうなのですが、それを表現する何らかの方法が必要なのです。
そのための一つの方法は、抽象的なモデルの型名に実際の型を関連付けるクラス(または構造体、enum)を作成することです。
class LegoRequestType: RequestType {
typealias Model = LegoModel
// Implement protocol requirements here
}
の配列を宣言するのは全く合理的です。
LegoRequestType
というのは、もし私たちが
frobulate
を渡す必要があるからです。
LegoModel
を毎回渡す必要があります。
連想型のこのニュアンスは、それらを使用する任意のプロトコルを特別なものにします。Swift 標準ライブラリはこのようなプロトコルを持ちますが、最も顕著なのは
Collection
または
Sequence
.
を実装したものを配列として作成できるようにする。
Collection
プロトコルを実装した配列やシーケンスプロトコルを実装したセットを作成できるように、標準ライブラリは "型消去"という技術を採用して、構造体型である
AnyCollection<T>
または
AnySequence<T>
. 型消しのテクニックはStack Overflowの回答で説明するにはかなり複雑ですが、Webを検索すればそれに関する記事がたくさんあります。
のビデオをお勧めします。 Alex Gallagher による PAT (Protocols With Associated Types) についてのビデオです。 をYouTubeで見ることができます。
関連
-
dyld: ライブラリがロードされていません。エラーの解決
-
[解決済み] Xcode 7のエラーです。"Missing iOS Distribution signing identity for ..." (iOS配布用署名IDがありません)
-
[解決済み] iOS 8 UITableViewのセパレータインセット0が機能しない件
-
[解決済み] フレームワークを使用したiOSアプリがデバイス上でクラッシュ、dyld: ライブラリがロードされない、Xcode 6 Beta
-
[解決済み] UIViewController のビューが表示されているかどうかを確認する方法
-
[解決済み] iOS 13 のフルスクリーンでモーダルを表示する
-
[解決済み] UIViewに角丸をつける
-
[解決済み] Swift 3, 4, 5 で dispatch_after GCD を書くにはどうしたらいいですか?
-
[解決済み] UITextFieldのテキストインセット?
-
[解決済み] swiftにおけるプロトコルの配列型および関数パラメータとしての使用法
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Objective-Cでデリゲートを作成するにはどうしたらいいですか?
-
[解決済み] Xcode 12、iOS Simulator用にビルドしても、iOS用にビルドされたオブジェクトファイルでは、アーキテクチャ「arm64」用にリンクされます。
-
[解決済み] Xcode 6のバグ:Interface Builderファイル内の不明なクラス
-
[解決済み] UIViewController のビューが表示されているかどうかを確認する方法
-
[解決済み] UITextFieldのテキスト変更イベント
-
[解決済み] 「GCC使用時に「Xcode/iOSのライセンスに同意するには管理者権限が必要です。rootでsudoを使用して再実行してください。
-
[解決済み] SwiftでURLから画像を読み込む/ダウンロードする
-
[解決済み] iOS 13でダークモードをオプトアウトすることは可能ですか?
-
[解決済み] UITextFieldのテキストインセット?
-
[解決済み] UIImageのサイズを変更する最も簡単な方法?