Можно ли установить тип переменной или константы равным протоколу в Swift? - PullRequest
0 голосов
/ 16 декабря 2018

Я новичок в Swift.Я пытаюсь сделать что-то похожее на:

let e:Equatable? where Equatable.Item == Int = nil

Возможно ли это?

С уважением,

shodz

Ответы [ 2 ]

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

Пока в рассматриваемом протоколе есть требования, которые используют associatedType или Self, вы не можете этого сделать.Короче говоря, это создает слишком много неоднозначности для компилятора.У Equatable есть требования, которые используют Self.Трудно что-то предложить, не зная вашего варианта использования, но во многих сценариях, где вы сталкиваетесь с этим, ответ заключается в том, чтобы поднять дженерики до уровня (например, если эта строка кода находится внутри функции, сделайте функцию общейсверх эквивалентного значения и используйте универсальный тип):

func doSomething<T: Equatable>(with value: T?) { ... }

или, в качестве альтернативы, для просмотра стирание типа .Но, вероятно, будет легче предлагать предложения, если мы немного больше узнаем о вашем случае использования.

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

Короткий ответ: вы не можете создать переменную на основе протокола.

Как указывается в официальной документации:

Протокол определяет схему методов, свойстви другие требования, которые удовлетворяют конкретной задаче или функциональности.Затем протокол может быть принят классом, структурой или перечислением, чтобы обеспечить фактическую реализацию этих требований.Говорят, что любой тип, который удовлетворяет требованиям протокола, соответствует этому протоколу.

Таким образом, минимальный объем работы, который требуется со стороны разработчиков, - это создание структуры или класса, который соответствуетопределенный протокол, скажем, Equatable.

Давайте снова возьмем пример из официальной документации.Протокол Equatable позволяет сравнивать два элемента одного типа, поэтому для его реализации необходимо реализовать метод ==(lhs: Type, rhs: Type,).

class StreetAddress {
    let number: String
    let street: String
    let unit: String?

    init(_ number: String, _ street: String, unit: String? = nil) {
        self.number = number
        self.street = street
        self.unit = unit
    }
}

extension StreetAddress: Equatable {
    static func == (lhs: StreetAddress, rhs: StreetAddress) -> Bool {
        return
            lhs.number == rhs.number &&
            lhs.street == rhs.street &&
            lhs.unit == rhs.unit
    }
}

Только теперь два экземпляра могутStreetAddress создается и сравнивается на основе вашего предиката.

...