2

例えば:

protocol SomeProtocol {
    typealias T
    func doSomething(something: T)
}
let a = Array<SomeProtocol>()

に準拠するオブジェクトの配列である配列が必要SomeProtocolです。理論的には問題ないように思えますが、次のエラー メッセージが表示されます。

関連付けられた型の要件が含まれているため、一般的な制約として使用できません。

そして、それは理にかなっていると思います。結局のところ、配列はジェネリック構造体でもあるため、コンパイラーは、両方がジェネリックSomeProtocolである実際に与えられた型を理解できません。Array

だから私の質問は - に準拠するオブジェクトの配列を持つことができるはずだと思いますSomeProtocol- これは現在 Swift 2.0 で可能ですか? 私はこれについて間違った方法で考えていますか?

4

2 に答える 2

3

このエラー メッセージの理由は、Array宣言が機能する場合に発生する次の問題です。

protocol SomeProtocol {
    typealias T
    func doSomething(something: T)
}
// has already some values
let a: Array<SomeProtocol> = [...]

// what type should be passed as parameter?
// the type of T in SomeProtocol is not defined
a[0].doSomething(...)

回避策として、任意のタイプのジェネリック ラッパー構造体を作成して、SomeProtocolタイプを指定できるようにすることができますT(Swift 標準ライブラリの AnyGenerator、AnySequence などのように)。

struct AnySomeProtocol<T>: SomeProtocol {
    let _doSomething: T -> ()
    // can only be initialized with a value of type SomeProtocol
    init<Base: SomeProtocol where Base.T == T>(_ base: Base) {
        _doSomething = base.doSomething
    }
    func doSomething(something: T) {
        _doSomething(something)
    }
}

タイプの配列を使用し[AnySomeProtocol<T>](必要なタイプに置き換えTます)、要素を追加する前に次のように変換しAnySomeProtocolます。

var array = [AnySomeProtocol<String>]()
array.append(AnySomeProtocol(someType))

// doSomething can only be called with a string 
array[0].doSomething("a string")
于 2015-09-11T21:23:46.380 に答える