Как ограничить родовые функции ассоциированными типами - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь взять два протокола, которые имеют одинаковый связанный тип и возвращают один и тот же тип, но без удачи.

protocol MyProtocol {
    associatedtype AssociatedType
}

func myFunc<T: MyProtocol, R: MyProtocol>(arg: T) -> R
    where T.AssociatedType == R.AssociatedType {
        return arg //Error-> Cannot convert return expression of type 'T' to return type 'R'
}

Возможно ли что-то подобное в Swift?

1 Ответ

0 голосов
/ 14 декабря 2018

Два типа (назовите их T и R) не обязательно являются эквивалентными только потому, что они соответствуют одному и тому же протоколу и используют один и тот же связанный тип.

По этой причине Array<Int>то же самое, что и Set<Int>, и должны быть свободно взаимозаменяемыми, потому что они оба соответствуют Collection, где Element равно Int.

Вот еще один контрпример:

protocol MyProtocol {
    associatedtype AssociatedType

    init()
}

protocol MySubProtocol1: MyProtocol where AssociatedType == Int {}
protocol MySubProtocol2: MyProtocol where AssociatedType == Int {}

struct S1: MySubProtocol1 {}
struct S2: MySubProtocol2 {}

func myFunc<T: MyProtocol, R: MyProtocol>(arg: T) -> R
    where T.AssociatedType == R.AssociatedType {
        return arg as! R // Let's see what would happen. Don't do this!
}

func produce<T: MySubProtocol1>(type: T.Type) -> T {
    return T()
}

func consume<T: MySubProtocol2>(arg: T, ofType: T.Type) {
    print(arg)
}

consume(arg: myFunc(arg: produce(type: S1.self)), ofType: S2.self)

Завершено из-за сигнала: ABORT TRAP (6)

Невозможно привести значение типа 'main.S1' (0x100e44210) к 'main.S2' (0x100e44228).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...