2016-03-29 3 views
2

プロトコルの汎用配列を使用する方法はありますか? 例えば、Swiftクラスのジェネリックスでプロトコルの配列を使用する

/* I want to use protocol like below, 
* but I can't because protocol is not concrete 
* so cannot make array of it */ 
class MyClass<T where T:MyProtocol, T:[MyProtocol]> { 
    let result: T 
} 

protocol MyProtocol { 
    init(with: String) 
} 

class SpecialThing: MyProtocol { 
    let appleWatch: AppleWatch 

    init(with: String) { 
     self.appleWatch = AppleWatch(with) 
    } 
} 

class SampleClass { 
    func test { 
     typealias listCallback = (MyClass<[SpecialThing]>, NSError) ->() 
     typealias oneCallback = (MyClass<SpecialThing>, NSError) ->() 
    } 
} 

プロトコルのサブクラスの一つのオブジェクトまたは配列が存在し得ます。 「タタリアス」は私を助けないと思います。

私が何かもっと簡単な方法を見つけたい.....これで

+0

同時にMyProtocol。 – Lachezar

+0

そうだと思います。私はMyClass内の汎用オブジェクトを初期化したい。すべてを研究しましたが、解決策がまだ見つかりません。 – macaron

+0

私が知る限り、これは不可能です。私が知っている唯一の "解決策"は、 'class MyClass { 結果:[T] }' –

答えて

1

私の最初の問題は、型シグネチャが間違っているということです。

class MyClass<T where T:MyProtocol, T:[MyProtocol]> 

やっようなものと同じタイプだこと:一度MyProtocolとしてそして再びMyProtocolの配列として、Tを再定義しているため

let t: String 
let t: [String] 
t = String("foo") 

コンパイラが文句を言うでしょう。あなたは両方を持つことはできません、あなたは1つだけ持つことができます。

0

回答:Eitherのような構文を使用します。

を可能に
enum Either<T, U> 
{ 
    case Left(T) 
    case Right(U) 

    var leftValue: T? 
    { 
     if case .Left(let leftValue) = self 
     { 
      return leftValue 
     } 

     return nil 
    } 

    var rightValue: U? 
    { 
     if case .Right(let rightValue) = self 
     { 
      return rightValue 
     } 

     return nil 
    } 
} 

:私はTがMyProtocolとの配列として指定されたジェネリック型を持つことが可能であるとは思わない

class MyClass<T: MyProtocol> 
{ 
    let result: Either<T, [MyProtocol]> 
} 
関連する問題