2016-07-05 8 views
1

ジェネリッククラスのタイプによって制約されるジェネリッククラスへの拡張をしようとしています。これは私が動作するはずと信じていたコードを簡略化したものである:汎用オブジェクトの制約付き拡張がタイプに一致しません

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>

これには何らかの回避策がありますか、それとも迅速なメーリングリストに進化提案として提出する必要がありますか?

注:すべてのコードはプレイグラウンドでテストされています。コピーして貼り付けるだけで試してみることができます。

+0

2番目のコードの問題は、TがStringProtocolに準拠していないことです。 StringProtocolに準拠する_no_型があるため、できません! – matt

+0

制約付き拡張は、TがStringProtocol(この例では)に準拠していることを内部的に宣言する必要があります。つまり、TをStringProtocolに準拠した型のものに割り当てることができます。同じロジックによって、オブジェクトのタイプもThing と同等でなければなりません。これを推測するのに十分な情報があります。 – gabriellanata

答えて

0

回避策として、selfからの値でThingの新しいインスタンスを作成することができます。スイフト2.2ような拡張制約で

extension Thing where T: StringProtocol { 
    func containedStringThing() -> ContainsStringThing { 
     return ContainsStringThing(stringThing: Thing<StringProtocol>(value: self.value)) 
    } 
} 

containedStringThing()関数は値型StringProtocolに準拠シングのインスタンスのために利用可能であることを意味します。スウィフトコンパイラはself.valueとしてStringProtocolの種類を推測することができれば

がいいだろう。そのような場合は、 ContainsStringThing(stringThing: Thing<StringProtocol>(value: self.value))の代わりに ContainsStringThing(stringThing: self)と書くことができます。あなたは間違いなく提案を記入する必要があります。

+0

悲しいことに、これは私にとってはうまくいかないでしょう。私が記事で述べたように、これは問題の単純化であり、Thingオブジェクトははるかに複雑で、内部の値そのものを転送するだけでは不十分です。 – gabriellanata

関連する問題