Подтвердить что ты не робот

Почему требуется принудительное развертывание в случае переименования и переключения?

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

enum Colours: Int {
case Red = 0, White, Black
}

var colours: Colours!
colours = .Red

switch colours! { // <-- why I have to unwrap colours? As you can see colours are declared as '!'
case .Red: break
default: break
}

Если переменная цвета не разворачивается, компилятор показывает мне, что ошибка: enter image description here

по-моему, это быстрая несогласованность, есть ли у кого-нибудь идеи?

4b9b3361

Ответ 1

При использовании в инструкции switch, даже неявно развернутой опции не разворачиваются автоматически. (Причина может заключаться в том, что вы не могли сопоставлять их с nil в противном случае.)

Итак, вам нужно развернуть (либо принудительно с colours!, который сработает, если colours == nil или с необязательной привязкой), или - альтернативно - соответствует .Red? который является ярлыком для .Some(.Red):

var colours: Colours!

switch colours {
case .Red?:
    break    // colours is .Red
default:
    break    // colours is .White, .Black or nil
}

То же самое относится к другим выражениям для сопоставления шаблонов, например

if case .Red? = colours {
    // colours is .Red 
} else {
    // colours is .White, .Black or nil
}

Также это не имеет ничего общего с типами перечисления, только с неявным развернутые варианты в шаблоне:

let x : Int! = 1

switch x {
case nil:
    break // x is nil
case 1?:
    break // x is 1
default:
    break // x is some other number
}

Ответ 2

Это связано с тем, что вы создаете переменную colours как необязательный тип. Если вы сделаете так:

var colours: Colours
colours = .Red

вам не придется раскрывать это значение

Если мы посмотрим, что такое необязательный тип, мы увидим, что это перечисление вроде:

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

И это может быть Some Тип типа Int например или None, и в этом случае оно имеет значение nil.

Когда вы это сделаете:

var colours: Colours!

вам непосредственно указывает !, что это не тип colours, но это тип enum ImplicitlyUnwrappedOptional<Colours>. В момент создания будет Some<Colours>, если оно равно, но с этим ! у вас есть, что это enum ImplicitlyUnwrappedOptional<Colours>, а в следующий момент это будет None. Вот почему вы должны использовать ! в switch:

Ваше значение colours имеет тип ImplicitlyUnwrappedOptional<Colours> и может быть colours или nil, и вам нужно прямо указать, что это colours введите `switch``.

Ответ 3

Вместо использования:

var colours: Colours!
colours = .Red

Просто используйте

var colours = Colours.Red

Это должно сделать трюк.