Как создать протокол с расширением типа универсальной функции - PullRequest
3 голосов
/ 10 апреля 2019

Я пытаюсь создать протокол с универсальной функцией, где 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 Ответ

4 голосов
/ 10 апреля 2019

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

То, что вы ищете, это протокол с ассоциированным типом .Связанный тип в протоколе означает, что соответствующий тип может решать, какой конкретный тип использовать вместо связанного типа, что позволяет вам использовать разные связанные типы в разных соответствующих классах.

protocol MyProtocol {
    associatedtype MyType: MainItem
    func myFunc() -> MyType
}

class ClassA: MyProtocol {
    func myFunc() -> Item1 {
        return Item1()
    }
}

class ClassB: MyProtocol {
    func myFunc() -> Item2 {
        return Item2()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...