Как Swift Array поддерживает правильное назначение подтипа Element? - PullRequest
0 голосов
/ 12 июля 2019

Я хочу привести или назначить пользовательский тип контейнера Swift к «совместимому» объявленному типу переменной контейнера, как это поддерживает нативный Swift Array.Приведенный ниже код является полным примером с выявленной проблемой.Array поддерживает его, моя пользовательская структура - нет.

Я изучил интерфейс Swift.Collection.Array и начал проверять исходный код.Каким-то образом Array поддерживает следующую строку: let array3: Array<HasHeading> = array2, в то время как мой пользовательский тип ThingContainer НЕ поддерживает ту же семантику let things3: ThingContainer<HasHeading> = things1

protocol HasHeading {
    var heading: Double { get }
}

struct Heading: HasHeading {
    let heading: Double
}

let heading1 = Heading(heading: 89.0)
let heading2 = Heading(heading: 90.0)


struct ThingContainer<T> {
    let thingOne: T
    let thingTwo: T

    init(thingOne: T, thingTwo: T) {
        self.thingOne = thingOne
        self.thingTwo = thingTwo
    }
}

let things1: ThingContainer<Heading> = ThingContainer(thingOne: heading1,
                                                      thingTwo: heading2)

let things2: ThingContainer<HasHeading> = ThingContainer(thingOne: heading1,
                                                         thingTwo: heading2)
//error: cannot convert value of type 'ThingContainer<Heading>' to specified type 'ThingContainer<HasHeading>'
let things3: ThingContainer<HasHeading> = things1
let things4: ThingContainer<HasHeading> = things2

let array1: Array<Heading> = [heading1,heading2]

let array2: Array<HasHeading> = [heading1,heading2]

let array3: Array<HasHeading> = array1
let array4: Array<HasHeading> = array2

Как поддерживается собственный тип Swift-типа: let array3: Array<HasHeading> = array1 У меня не может быть ничего, что можно сделатьс содержащимся типом.Это форма автоматического моста?

1 Ответ

0 голосов
/ 12 июля 2019

То, что вы ищете, называется универсальной ковариацией, и, к сожалению, Swift не поддерживает это.Ковариация магических жестких кодов компилятора для небольшого набора типов, таких как коллекции стандартных библиотек и Optional<T>.

Для получения дополнительной информации по этому вопросу я предлагаю прочитать Пятница, вопросы и ответы 2015-11-20: Ковариацияи контравариантность Майка Эша

...