2015-08-26 2 views
0

Следующий код:Как использовать протокол с typealias как параметр func?

protocol ProtocolA { 
} 

protocol ProtocolB { 
    typealias T: ProtocolA 
    var value : Array<T> { get set } 
} 

class ProtocolC { 
    func method<T: ProtocolA>(value: ProtocolB<T>) 
    { 

    } 
} 

Урожайность эти ошибки:

error: cannot specialize non-generic type 'ProtocolB' 
func method<T: ProtocolA>(value: ProtocolB<T>) 

error: generic parameter 'T' is not used in function signature 
func method<T: ProtocolA>(value: ProtocolB<T>) 

error: protocol 'ProtocolB' can only be used as a generic constraint because it has Self or associated type requirements 
func method<T: ProtocolA>(value: ProtocolB<T>) 

Может кто-нибудь объяснить мне, почему это не возможно? Это ошибка или умышленное?

+0

Что вы пытаетесь сделать с помощью 'method'? –

+0

Допустим, у меня разные реализации ProtocolA и ProtocolB для разных аппаратных устройств. Тогда метод должен выполнить на нем некоторый алгоритм. Теперь я не могу использовать подклассы, поскольку конкретные реализации уже должны подклассифицировать другой класс, который не должен быть раскрыт. – V1ru8

+0

Я могу на самом деле обойти это, тем более, что я хотел бы понять, почему это невозможно, поскольку он выглядит как допустимый пример использования генериков. – V1ru8

ответ

2

Вы не можете специализироваться общий протокол с <>.

Вместо этого, вы можете:

func method<B: ProtocolB where B.T: ProtocolA>(value: B) { 
} 

Это говорит, method принимает B где B соответствует ProtocolB и его T соответствует ProtocolA.

И в этом случае вам не нужно where B.T: ProtocolA, потому что это очевидно.

func method<B: ProtocolB>(value: B) { 
    ... 
} 
1

Удалить <T> после аргумента B в определении method. Вам также не нужен <T: ProtocolA> в сигнатуре метода.

protocol ProtocolA { 
} 

typealias T = ProtocolA 

protocol ProtocolB { 
    var value : [T] { get set } 
} 

class ProtocolC { 
    func method(value: ProtocolB) 
    { 

    } 
} 
+0

Это решает только две из этих проблем. Протокол «error: protocol» ProtocolB может использоваться только в качестве общего ограничения, поскольку он имеет собственные или связанные требования типа, которые все еще не решены. – V1ru8

+0

Это сложнее. Я думаю, что это потому, что указание параметра типа «ProtocolB» недостаточно, потому что 'typealias' каким-то образом требует больше информации о классе' ProtocolB'. Если вы выберете 'typealias' и просто укажите тело как' var value: Array {get set} '(или, еще лучше,' var value: [T] {get set} '), то он компилируется. – NRitH

+0

Можете ли вы опубликовать полный код? Я не собираюсь это компилировать. – V1ru8

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