2016-09-13 6 views
4

冗長導入は、私はこのような何かを持っていると思います。それは自己または関連タイプの要件を持っている のでスウィフト一般Existentials

プロトコル「P」だけの一般的な制約として使用することができます。私は本当にユースケースの数のためにこれを必要とし、これは(私が思います)

は「第1のプロトコル指向言語」をわかりやすくします。これがないとSwiftの型システムと戦い、associatedtypeというプロトコルがあるはずの一般的な抽象クラスを作ります。

は、ここに1つの例ですが、一般的なクラスのために私が最も、デリゲートを打つこと:私はGenericClassDelegateプロトコルを記述することができますが

protocol GenericClassDelegate : class { 
    associatedtype ItemType 
    func didDoThat(who : GenericClass<ItemType>) 
} 

class GenericClass<T> { 
    weak var delegate : GenericClassDelegate<where .ItemType == T>? // can't do that 

    func notify() { 
     delegate?.didDoThat(who: self) 
    } 
} 

、(現在スウィフト3)私は、変数や定数を持つことはできませんそのタイプ(または制限に適合するタイプ)。私の質問がありとして

は、How to use generic protocol as a variable typeまたはSwift delegate protocol for generic classでこの質問を混同しないでください:

  1. は、スウィフトに一般Existentialsを導入する上で現在存在する任意の提案や議論がありますが、計画は何ですか?いいえ、どうすれば参加できますか?
  2. スウィフトがそのような方法で(Associated Typesではあるが一般化されたExistentialsなしで)設計されていれば、それは多少のアーキテクチャ上のシフトを意味するかもしれない。私は委任パターンをどのように置き換えると思いますか?

P.デリゲートの関数をクロージャーでキャプチャするときにタイプイレーズのサンクを提案しないでください。それは非常に間違っていて誤解を招きます。私もそれを松葉杖と呼んでいます。

が誤って別の解決策を見つけたが、私は完全にそれに満足していないよ:

protocol GenericClassDelegate : class { 
    associatedtype ItemType 
    func didDoThat(who : GenericClass<ItemType, Self>) 
} 

class GenericClass<T, Delegate : GenericClassDelegate> where Delegate.ItemType == T { 
    weak var delegate : Delegate? 

    func notify() { 
     delegate?.didDoThat(who: self) 
    } 

    init(_ delegate : Delegate?) { 
     self.delegate = delegate 
    } 
} 

// Delegates must be final classes, otherwise it does not compile 
// because I used Self in GenericClassDelegate 
final class GenericClassDelegateImp<T> : GenericClassDelegate { 
    typealias ItemType = T 
    func didDoThat(who: GenericClass<T, GenericClassDelegateImp>) { 
     print(who) 
    } 
} 

// Usage: 
var delegate = GenericClassDelegateImp<Int>() 
var genericClass = GenericClass<Int, GenericClassDelegateImp<Int>>(delegate) 

答えて

2

は、スウィフトに一般Existentialsを導入する上で現在存在する任意の提案や議論がありますが、計画は何ですか?いいえ、どうすれば参加できますか?

これは一般的に要求される機能であり、すでに迅速な進化のための予備的な設計作業が行われていました。しかし、現時点では、コアチームとコミュニティは、機能に影響を与えるABIの安定性、またはLattnerが「Swift 4 Phase 1」と定義するものに焦点を当てています。

フェーズ2が開始されると、それについてもっと詳しく聞くでしょう。その人気を考えれば、それはSwift 4の一部になると予想されます。

スウィフトが(関連付けられたタイプではあるが、一般化されたExistentialsなしで)設計されていれば、多分アーキテクチャ上のシフトを意味します。私は委任パターンをどのように置き換えると思いますか?

推移的な解決策として、タイプ消去されたラッパーを使用できます。一般的に、クラスの動的ディスパッチと継承を利用して型を削除します。

protocol Fancy { 
    associatedtype Value 
    var value: Value 
} 

struct FancyMatter<Value> { 
    let value: Value 
} 

class AnyFancyBoxBase<P: FancyProtocol>: AnyFancyBox<P.Value> { 
    let base: P 
    override var value: P.Value { return base.value } 
    init(_ base: P) { self.base = base } 
} 

class AnyFancyBox<Value> { 
    var value: Value { fatalError() } 
} 

var box: AnyFancyBox<Int> = AnyFancyBoxBase(FancyMatter(1)) 

how the Standard Library implements type-erased wrappersをご覧ください。