У меня есть Свифт протокол, определяемый следующим образом:Далее сдерживая обобщенную функцию от Swift протокола
protocol MyProtocol {
func genericMethod<T:MyProtocol>(param:T) ->()
}
я могу реализовать универсальный метод в базовом классе, как это:
class MyBaseClass : MyProtocol {
func genericMethod<T where T:MyProtocol>(param:T) ->() {
println("Performing generic method for type \(T.self)")
}
}
class MySubClass : MyBaseClass {
...
}
До сих пор , так хорошо. Я могу реализовать этот метод, и он компилируется и работает просто отлично.
Теперь я хочу сделать что-то подобное, но в моем базовом классе я хочу еще больше ограничить тип универсального метода, потребовав, чтобы он соответствовал протоколу, например Comparable
. Я стараюсь это:
class MyBaseClass : MyProtocol {
func genericMethod<T where T:MyProtocol, T:Comparable>(param:T) ->() {
println("Performing generic method for type \(T.self)")
}
}
После того, как я добавить дополнительное ограничение на тип T
, класс MyClass
не будет компилироваться, так как он не соответствует протоколу больше.
Похоже, что добавление дополнительного ограничения на общий тип не должно приводить к его прекращению в соответствии с протоколом. Что мне не хватает? Мне кажется, что протокол говорит, что genericMethod
должен быть передан параметр типа, который соответствует MyProtocol
. Когда я иду осуществить это в MyBaseClass
- только один из возможных вариантов реализации MyProtocol
- что я должен быть в состоянии ограничить, что осуществление в дальнейшем, говоря, что параметр Myst соответствует Comparable
в дополнении кMyProtocol
Есть ли способ уточнить общий тип в базовой реализации, как я пытаюсь сделать здесь?
Я не понимаю, почему вы удивлены. Возможно, мне не хватает чего-то очевидного, но мне кажется, что в протоколе говорится: «Кто примет меня, должен реализовать« genericMethod »с параметром, являющимся его собственным типом. Но« T: MyBaseClass, T: Comparable »- это собственный тип MyBaseClass , поскольку MyBaseClass не использует Comparable, поэтому, как компилятор говорит, вы нарушили договор, установленный протоколом. – matt
Использование ссылки 'Self' в протоколе было всего лишь одним из способов продемонстрировать проблему. проблема, если я использую один протокол, а затем другой. Я обновлю вопрос, чтобы было более понятно, почему я удивлен этим поведением –
ОК, спасибо за ревизию. Ну, ответ на вопрос о том, почему компилятор не нравится это требование не соответствует. Требование к протоколу 'func genericMethod (param: T) ->()' не является тем же, что и 'func genericMethod (param: T) ->() '.Вы говорите в своеобразной ментальной оправдательной сноске «одна - более ограниченная версия другой», но это не имеет значения для компилятора; Дело в том, что это не одно. –
matt