2016-02-10 2 views
3

Учитывая классGeneric реализации делегата в Swift

Calss<A: Type1, B: Type2> 

бы это было возможно создать свойство внутри класса, который будет использовать общий тип из класса делегата (протокол)? например

protocol CalssDelegate{ 
    func decorate(first: A, second: B) -> Void 
} 

Другими словами, как бы я мог добиться безопасности типа при создании протокола делегата общего класса?

+0

Да. Это была первоначальная реализация, которую я имел в виду. – Mercurial

+0

Обновлено одним возможным способом; однако ограничены ограничениями типа ('Type1',' Type2'), которые сами по себе могут использоваться как типы (гетерогенные протоколы). – dfri

ответ

0

Вы могли бы позволить «видовым» типам делегата быть гетерогенными протоколами, к которым вы соответствуете типам, которые вы хотите дженерик A и B, соответственно, что позволяет Type1 и Type2, которые будут использоваться в качестве фактических типов в «общем» методе чертежи вашего протокола делегата.


Настройки родовых ограничений типа Type1 и Type2 (ограничение: они должны быть разнородными) и протокол делегата MyClassDelegate:

/* Generic type constraints */ 
protocol Type1: CustomStringConvertible { 
    init(_ value: Int) 
    func foo() 
} 
protocol Type2: CustomStringConvertible { 
    init(_ value: Int) 
    func bar() 
} 

/* Delegate protocol */ 
protocol MyClassDelegate { 
    func decorate(first: Type1, second: Type2) -> Void 
} 

Настройка два примера классов с помощью «родового» делегата для обратных вызовов от одного класса к другому.

/* class using the delegate */ 
class MyDifferentClass<A: Type1, B: Type2> { 
    var foo: A = A(0) 
    var bar: B = B(0) 
    var delegate: MyClassDelegate? 

    var someInt : Int = 1 { 
     didSet { 
      delegate?.decorate(foo, second: bar) 
     } 
    } 
} 

/* class conforming to MyClassDelegate */ 
class MyCurrentClass<A: Type1, B: Type2>: MyClassDelegate { 
    var myDifferentClass = MyDifferentClass<A, B>() 

    init() { 
     myDifferentClass.delegate = self 
    } 

    // MyClassDelegate 
    func decorate(first: Type1, second: Type2) { 
     first.foo() 
     second.bar() 

     print("first: \(first)", "second: \(second)") 

     // ... 
    } 
} 

типов Пример: использование

/* conforming some types to your generic type (constraint) protocols */ 
extension Int: Type1 { 
    func foo() { 
     print("foo!") 
    } 
} 

extension Double: Type2 { 
    func bar() { 
     print("bar!") 
    } 
} 

Пример:

/* Example usage */ 
var a = MyCurrentClass<Int, Double>() 

a.myDifferentClass.someInt += 1 
/* foo! 
    bar! 
    first: 0 second: 0.0 */ 

Этот метод является действительным до тех пор, как протоколы типа ограничений Type1 и Type2 являются гетерогенными, то есть, не содержат некоторые ассоциированные типы.

+0

Не совсем то, что я имел в виду, но применимо в некоторых случаях. – Mercurial