2016-11-22 6 views
2

У меня возникла странная проблема, вот она: я хочу ограничить один общий тип другим родовым типом.Дженерики дженериков в Swift 3

Позвольте мне объяснить, у меня есть простой общий тип:

class Simple<T : Equatable> { ... } 

И я хочу иметь другую родовую ограничение типа с этой простой (общий) тип:

class Complex<U : Simple> { ... } // WRONG! 

Конечно, это не компилируется и не так:

class Complex<U : Simple<T : Equatable>> { ... } // WRONG! 

ни:

class Complex<U : Simple<T>> where T : Equatable { ... } // WRONG! 

Единственный способ я нашел:

class Complex<T : Equatable, U : Simple<T>> { ... } 

Так что мне нужно повторить T на каждом создании экземпляра:

let x = Complex<Date, Simple<Date>>() 

Worst, представьте себе, если у меня есть что-то вроде этого:

class SimpleThing : Simple<Thing> { ... } 
let y = Complex<Thing, SimpleThing>() 

Как я могу объявить Complex для нас таким образом:

let x = Complex<Simple<Date>>() 
let y = Complex<SimpleThing>() 

Возможно ли это только в Swift 3?

Заранее спасибо.

ответ

1

Если я понимаю, что вы хотите сделать правильно, это может быть достигнуто протоколом со связанным типом. Вы можете сделать свой простой класс совместимым с ним, а затем ограничить параметр типа в Complex как его соответствующие типы и, наконец, поставить квалификацию на связанный тип. Должно быть что-то вроде этого:

protocol SimpleType { 
    associatedtype Assoc 
} 

class Simple<T: Equatable>: SimpleType { 
    typealias Assoc = T 
} 

class Complex<U: SimpleType> where U.Assoc: Equatable { 
    init() { 

    } 
} 

let c = Complex<Simple<Date>>() 
+0

Спасибо, это немного сложное решение для кажущейся легкой проблемы. Во всяком случае, очень полезно увидеть эту проблему таким образом. – Zaphod

Смежные вопросы