Быстрые условные соответствия с универсальным типом - PullRequest
8 голосов
/ 06 марта 2019

Я пытаюсь заставить работать расширение Swift с двумя универсальными типами.Я пытался сделать пример.

У нас есть ящик, где мы можем для разных типов.

class Box<E> {
    var value: E
    init(val: E) {
        value = val
    }
}

Теперь у нас есть специальный Itemtype, который снова может иметь разные типы

class Item<Type> {
    var value: Type
    init(val: Type) {
        value = val
    }
}

Так что теперь мы можем легко создать Box<Item<Int>>.Но, возможно, мы хотим изменить его на Box<Item<String>>. Поэтому мне бы хотелось, чтобы расширение было изменено с Box<Item<A>> на Box<Item<B>>

. Что работает, так это следующее

extension Box where E: Item<Any> {
    func mapOnItem(function: (Any) -> Any) -> Box<Item<Any>> {
        return Box<Item<Any>>(val: Item(val: function(value.value)))
    }
}

Но это не очень полезно, потому что у нас нет связи между возвращаемым значением функции и возвращаемым значением mapOnItem.

Итак, я попытался исправить, но у меня не получается.Мое понимание было бы представить здесь другую переменную общего характера.

extension Box<A> where E: Item<A> {
    func mapOnItem<B>(function: (A) -> B) -> Box<Item<B>> {
        return Box<Item<B>>(val: Item(val: function(value.value)))
    }
}

Я получаю ошибку

Ограниченное расширение должно быть объявлено для неспециализированного универсального типа 'Box' с ограничениями, указанными в предложении 'where'

У вас есть какие-нибудь подсказки для меня?Это вообще возможно?

Спасибо за помощь

Мартин

1 Ответ

10 голосов
/ 06 марта 2019

Ограничение на расширение может ограничивать тип заполнителя E конкретными типами или протоколами, например:

extension Box where E: Item<Any> {}
extension Box where E == String {}
extension Box where E: Numeric {}

Но вы не можете наложить общее ограничение на расширение:

extension Box<A> where E: Item<A> {}
// Error: Constrained extension must be declared on the unspecialized generic
// type 'Box' with constraints specified by a 'where' clause

Решение состоит в том, чтобы ограничить метод вместо этого:

extension Box  {
    func mapOnItem<A, B>(function: (A) -> B) -> Box<Item<B>> where E: Item<A> {
        return Box<Item<B>>(val: Item(val: function(self.value.value)))
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...