Разница между связанными и необработанными значениями в быстрых перечислениях

Переменные Swift имеют как связанные, так и необработанные значения. Но варианты использования этих значений мне не понятны. Поэтому я был бы очень признателен, если кто-нибудь сможет объяснить разницу между связанными и необработанными значениями, пример будет очень полезен.

Ответ 1

Необработанные значения - это когда каждый случай в перечислении представлен значением, заданным временем компиляции. Сродства к константам, т.е.

let A = 0
let B = 1

похож на:

enum E: Int {
    case A  // if you don't specify, IntegerLiteralConvertible-based enums start at 0
    case B
}

Итак, A имеет фиксированное исходное значение 0, B of 1 и т.д., установленное во время компиляции. Все они должны быть одного типа (тип исходного значения - для всего перечисления, а не для каждого отдельного случая). Они могут быть буквально-конвертируемыми строками, символами или цифрами. И все они должны быть разными (никакие две перечисления не могут иметь одинаковое значение).

Связанные значения больше похожи на переменные, связанные с одним из случаев перечисления:

enum E {
    case A(Int)
    case B
    case C(String)
}

Здесь A теперь имеет связанный Int, который может содержать любое целочисленное значение. B, с другой стороны, не имеет связанного значения. И C имеет ассоциированный String. Связанные типы могут быть любого типа, а не только строк или чисел.

Любое заданное значение типа E будет удерживать только один из связанных типов, т.е. либо Int, если перечисление является A, или String, если перечисление является C. Ему нужно только достаточно места для большего из двух. Подобные типы иногда называются "дискриминационными объединениями" - объединение является переменной, которая может содержать несколько разных типов, но вы знаете (из случая перечисления), который он держит.

Они могут даже быть родовыми. Наиболее распространенным примером которого является Optional, который определяется следующим образом:

enum Optional<T> {
    case .Some(T)
    case .None
}

Ответ 2

enter image description here

Необработанные ценности

enum Airport: String {
    case munich = "MUC"
    case sanFrancisco = "SFO"
    case singapore = "SIN"
}

A raw value - это то, что уникально идентифицирует значение определенного типа. "Уникально" означает, что вы не потеряете какую-либо информацию, используя необработанное значение вместо исходного значения.

Связанные ценности

enum Airport {
    case munich
    case sanFrancisco
    case singapore
    case london(airportName: String)
}

Swift позволяет нам привязать одно (или несколько) дополнительных значений к регистру enum. Эти значения называются associated values.

Как только мы добавим associated values к нашим enum случаям, мы сделаем невозможным, чтобы перечисление было инъективным относительно его raw value.

Мы не можем восстановить original enum по raw value, потому что нет способа определить, какое из связанных значений выбрать.

Swift enum может иметь raw values или associated values.

Подробнее здесь

Ответ 3

Ответы @Airspeed Velocity и @yoAlex5 хорошо объясняют разницу, но они утверждают, что

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

Это не так для Swift 4 и 5. Здесь - хорошая иллюстрация того, что они оба в одном перечислении. Конечно, вам понадобятся значения по умолчанию для инициализатора необработанных значений.