Почему требуется принудительное развертывание в случае переименования и переключения?
Я заметил странное быстрое поведение, потому что, по-моему, переменная цвета не должна быть развернута в случае коммутатора, написанного ниже, но без разворачивания компилятора отображается сообщение об ошибке.
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]()
по-моему, это быстрая несогласованность, есть ли у кого-нибудь идеи?
Ответы
Ответ 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
Это должно сделать трюк.