タイプに応じて文字列を作成したいと思います(必要があればURLの一部)。プロトコルタイプを汎用関数に渡すにはどうすればよいですか?
は、この典型的なコードを考えてみましょう:
import Foundation
protocol TestP {
var p: Int { get }
}
protocol TestQ: TestP {
var q: Int { get }
}
struct TestR: TestQ {
var p = 1
var q = 2
}
func toDescription<T: TestP>(type: T.Type) -> String {
switch type {
case is TestR.Type: return "Arrrr"
default: return "unsupported"
}
}
これは合理的に素敵なようです。私は安全でない尺度(文字列)に頼る必要はなく、別の列挙型も必要としませんでした。
のは、いくつかの使用例を見てみましょう。最初の2つの関数は(!ジェネリックバージョンは特にいいです)大丈夫です
func example1<T: TestP>(val: T) {
print("Processing \(toDescription(type: T.self))")
}
func example2() {
print("Processing \(toDescription(type: TestR.self))")
}
func example3() {
print("Processing \(toDescription(type: TestQ.self))")
}
が、第三は、コンパイルされません:
Error: in argument type
TestQ.Protocol.Type
,TestQ.Protocol
does not conform to expected typeTestP
TestP.Type
とTestP.Protocol
はパラメータとしても機能しません。
プロトコルタイプを(汎用)関数に渡すにはどうすればよいですか?
これは正当な理由でコンパイルされません。たとえば、「TestP」には「静的」要件があります。 'toDescription'の中から' type'でその要件を呼び出すことはできますが、 'TestQ.self'を渡すことができれば、呼び出す実装はありません。 – Hamish
これは(これらの危険な状況を防ぐために)より大きな制限の一部ですが、そうでなければ完全に安全なエッジケースでいっぱいです。つまり、[プロトコルは自分自身に準拠していません](http:// stackoverflow .com/questions/33112559/protocol-doesnt-conform-to-itself) - 'TestP'に準拠する型として' TestQ'を使うことはできません。 – Hamish
@Hamishわかりました。私は 'func f(type:T.Protocol)'を書くことができると期待しています。その場合、コンパイラはプロトコルタイプで静的メンバーを呼び出さないことをチェックできます。 (まあ、私が書いたバージョンでも、失敗する可能性があるため静的メンバーにアクセスできなくなる可能性があります) –
Raphael