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' が非ジェネリックになります

これを修正する方法を探したところ、 type: 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
    }
}

拡張機能を制限できるようになりましたが、別のエラー メッセージが表示されます。

タイプ 'Thing<T>' の値を予期される引数タイプ 'Thing<StringProtocol>' に変換できません

基本的に、それ自体はTプロトコルに準拠していることを認識していますStringProtocolが、オブジェクト全体を参照する場合は認識していませんThing<T>

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

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

4

1 に答える 1

0

回避策として、self からの値を使用して Thing の新しいインスタンスを作成できます。

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

Swift 2.2 では、そのような拡張制約は、値の型が StringProtocol に準拠する Thing のインスタンスに対して、含まれる StringThing()関数が使用可能になることを意味します。

Swift コンパイラがself.valueの型をStringProtocolとして推論できればいいのですが。そのような場合、 の代わりに 書くことができます。あなたは間違いなく提案書を記入する必要があります。ContainsStringThing(stringThing: self)ContainsStringThing(stringThing: Thing<StringProtocol>(value: self.value))

于 2016-07-05T21:45:16.963 に答える