2015-05-23 2 views
8

Из-за отсутствия ковариации Swift мне нужно некоторое обходное решение. Я прихожу из Java-мира, поэтому я инстинктивно пытался создать ограничение от одного типа к другому родовому типу.Общий параметр, ограниченный другим общим параметром

Так что я написал следующий класс:

class Factory<T: AnyObject> { 
    let factoryClosure:() -> T 

    init(closure:() -> T) { 
     factoryClosure = closure 
    } 

    init<CHILD: T>(childFactory: Factory<CHILD>) { 
     factoryClosure = {() -> T in 
      return otherFactory.create() 
     } 
    } 

    func create() -> T { 
     return factoryClosure() 
    } 
} 

я ожидал, чтобы это работало нормально. У меня есть T и CHILD должен быть подклассом T. Компилятор Swift однако не согласен и показывает следующую ошибку на линии с init<CHILD: T>.

Наследование от непротокольного, не-класса «T»

Я попытался родовое наследование параметров в другом сценарии, а также. Добавление следующего класса в класс (и удаление init, вызывающего ошибку компиляции).

func to<OTHER where OTHER: AnyObject, T: OTHER>() { 

} 

Это дает в основном тот же результат.

типа «Т» вынужден типа без протокола «OTHER»

Все, что я, хотя может работать не сделал, и закончилась с подобным сообщением об ошибке. Это ошибка в Swift? Или я чего-то не хватает? Или это особенность Свифта и никогда не будет работать, как я думал?

+0

Что вы на самом деле пытаетесь достичь? Фактическая цель, а не какой-то код, который пытается достичь указанной неустановленной цели. –

+0

Цель, которую я пытаюсь достичь, - это иметь что-то, что позволило бы мне обходиться без ковариантности (если я правильно напомню этот термин). В Java я бы использовал 'Factory 'и может проходить в любом экземпляре' Factory', который будет иметь параметр типа 'MyObject' или его дочерних элементов. –

+0

Это все еще звучит как средство, а не конец. Какова фактическая цель? –

ответ

0

Если вы хотите передать какой-либо Factory<T> где T имеет тип AnyObject вы просто должны написать:

init(childFactory: Factory<T>) { 
    factoryClosure = {() -> T in 
     return otherFactory.create() 
    } 
} 

, поскольку T автоматически ограничивается вашим классом.

+0

Это не решит проблему, потому что вы могли бы пройти только на 'Factory 'и не' Factory 'где 'Z' является подклассом' T'. –

+0

Я думаю, что это решает вашу проблему, потому что если 'Z' является подклассом' T', это также тип 'AnyObject'.Поэтому вы также можете передать 'Factory ' ('T' является просто заполнителем для типа, который соответствует' AnyObject') – Qbyte

+0

В контексте 'T' уже ограничен классом, который вы создаете. Поэтому, если вы делаете 'let zFactory = Factory () {return Z()}; let tFactory = Factory (childFactory: zFactory) 'это не сработает. –

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