#swift #generics #protocols #swift-protocols
#swift #дженерики #протоколы #swift-протоколы
Вопрос:
Я пытаюсь создать протокол с универсальной функцией, где T не просто равно типу, но и расширяет его.
class MainItem {}
class Item1: MainItem {}
class Item2: MainItem {}
protocol MyProtocol {
func myFunc<T: MainItem>() -> T // T extends MainItem
}
class ClassA: MyProtocol {
func myFunc() -> Item1 { // not MainItem
return Item1()
}
}
class ClassB: MyProtocol {
func myFunc() -> Item2 { // not MainItem
return Item2()
}
}
Но я получаю эту ошибку
Тип ‘ClassA’ не соответствует протоколу ‘MyProtocol’
потому Item1
что не равно MainItem
(оно расширяет его). Как вы можете заставить его работать?
Например, в Java все можно сделать с помощью абстрактного класса:
abstract class MyProtocol {
abstract <T extends MainItem> T myFunc()
}
Комментарии:
1. @Dimple пожалуйста, не добавляйте нерелевантные теги. Тег iOS следует использовать только для вопросов, конкретно касающихся платформы iOS, но этот вопрос явно не зависит от платформы и касается только функции языка программирования Swift.
Ответ №1:
Дженерики не подходят для ваших требований. Когда вы объявляете универсальную функцию в протоколе, параметр универсального типа будет означать, что одна и та же функция работает для всех типов, которые удовлетворяют ограничению универсального типа, но сигнатура функции все равно должна быть неизменной для всех соответствующих типов.
То, что вы ищете, — это протокол с соответствующим типом. Связанный тип в протоколе означает, что соответствующий тип может решить, какой конкретный тип использовать вместо связанного типа, следовательно, позволяя вам использовать разные связанные типы в разных соответствующих классах.
protocol MyProtocol {
associatedtype MyType: MainItem
func myFunc() -> MyType
}
class ClassA: MyProtocol {
func myFunc() -> Item1 {
return Item1()
}
}
class ClassB: MyProtocol {
func myFunc() -> Item2 {
return Item2()
}
}
Комментарии:
1. Большое вам спасибо. Это то, что я искал!