ジェネリッククラスのタイプによって制約されるジェネリッククラスへの拡張をしようとしています。これは私が動作するはずと信じていたコードを簡略化したものである:汎用オブジェクトの制約付き拡張がタイプに一致しません
struct Thing<T> {
var value: T
}
struct ContainsStringThing {
var stringThing: Thing<String>
}
extension Thing where T == String { // <-- Error location
func containedStringThing() -> ContainsStringThing {
return ContainsStringThing(stringThing: value)
}
}
しかし、私は次のようなエラーメッセージが出ます:
を作ります同じタイプの要件は、一般的なパラメータ「T」非ジェネリック
これを修正する方法を探して、タイプの代わりに拡張子を制限するプロトコルを使用するように提案しました:link to article
protocol StringProtocol { }
struct Thing<T> {
var value: T
}
struct ContainsStringThing {
var stringThing: Thing<StringProtocol>
}
extension Thing where T: StringProtocol {
func containedStringThing() -> ContainsStringThing {
return ContainsStringThing(stringThing: self) // <-- Error location
}
}
今では私は拡張子を制約せんが、それは別のエラーメッセージを示しています:私はこれで終わったことをやった後
は、型の値を変換できません「シング< T>」に期待される引数の型「シング< StringProtocol>」
は、基本的には、今ではT
は、それ自体でプロトコルStringProtocol
に準拠していることを知っているが、目を参照するとき、それはそれを知りません全体のオブジェクトThing<T>
。
これには何らかの回避策がありますか、それとも迅速なメーリングリストに進化提案として提出する必要がありますか?
注:すべてのコードはプレイグラウンドでテストされています。コピーして貼り付けるだけで試してみることができます。
2番目のコードの問題は、TがStringProtocolに準拠していないことです。 StringProtocolに準拠する_no_型があるため、できません! – matt
制約付き拡張は、TがStringProtocol(この例では)に準拠していることを内部的に宣言する必要があります。つまり、TをStringProtocolに準拠した型のものに割り当てることができます。同じロジックによって、オブジェクトのタイプもThing と同等でなければなりません。これを推測するのに十分な情報があります。 –
gabriellanata