2015-08-01 2 views
2

Почему в этом операторе switch используется оператор типа cast (as) вместо его условной формы (как?)?Нужно прояснить оператор Type Casting в Swift

Я думал, что оператор типа может быть только (как?) Или (как!) ...? Документация Apple Swift не дает адекватного объяснения этому.

Вот пример в Swift документации:

var things = [Any]() 

things.append(0) 
things.append(0.0) 
things.append(42) 
things.append(3.14159) 
things.append("hello") 
things.append((3.0, 5.0)) 
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman")) 
things.append({ (name: String) -> String in "Hello, \(name)" }) 

for thing in things { 
     switch thing { 
     case 0 as Int: 
      println("zero as an Int") 
     case 0 as Double: 
      println("zero as a Double") 
     case let someInt as Int: 
      println("an integer value of \(someInt)") 
     case let someDouble as Double where someDouble > 0: 
      println("a positive double value of \(someDouble)") 
     case is Double: 
      println("some other double value that I don't want to print") 
     case let someString as String: 
      println("a string value of \"\(someString)\"") 
     case let (x, y) as (Double, Double): 
      println("an (x, y) point at \(x), \(y)") 
     case let movie as Movie: 
      println("a movie called '\(movie.name)', dir. \(movie.director)") 
     case let stringConverter as String -> String: 
      println(stringConverter("Michael")) 
     default: 
      println("something else") 
     } 
    } 

Вот ссылка на Apple Swift documentation on Type Casting

+0

Put интересный пример для «case is», то есть «case is Int, is String». См. Http://stackoverflow.com/questions/25724527/swift-test-class-type-in-switch-statement/32497118#32497118 – Abhijeet

ответ

4

Вы могли бы найти ответ самостоятельно, если вы читали note на дне:

Случаи оператора выключателя используют принудительную версию оператора литого типа (как, а не как?) для проверки и перевода в определенный тип. Эта проверка всегда безопасна в контексте оператора case switch.

(курсив мой)

Here является блог Apple, который конкретизирует разница между as?, as и as!.

+1

Эта же документация также относится к «принудительной версии оператора литья типа» как " '(as!)' "во многих разных местах документа, поэтому я могу понять путаницу Уолтера. –

+0

Да, я прочитал эту заметку. В этой заметке говорится «принудительная версия оператора литого типа», который является ** a! **. Это не объясняет, почему восклицательный знак (!) Не включен. Кроме того, в вашей ссылке объясняется, что ** как ** является гарантированным преобразованием. Я не уверен, что это значит. Документация Swift только объясняет ** как? ** и ** как! **. –

+1

The!не включается, потому что ошибка времени выполнения никогда не может произойти - оператор 'case' * гарантирует *, что если' thing' не является 'Int', кастинг не выполняется. Я согласен с вами в том, что это сбивает с толку. – Glorfindel

1

as в case 0 as Int: или case let someInt as Int: является частью типа литья шаблонSwift Language Reference случае метка переключателя заявление определяется как

случае этикеткислучай случай-пункт-лист:
регистр пункт-лист → шаблон охранник-раздел неавтоматического | шаблон охранник придаточного неавтоматического, кейс-пункт-лист

, где рисунок может быть (среди других случаев)

модели → Значение-связывающим-паттерн
модели → тип-литейно-паттерн
узор → экспрессии-узор

и типовой литой образец

type-casting-pattern → is-pattern | а-модель
это-модельявляется типа
, как-шаблон → шаблон в типа

Так у вас есть, например

case let someInt as Int: 
╰──────────────────────╯ case-label 
    ╰────────────────╯ case-item-list -> type-casting pattern 
        ╰─╯ type 
       ╰╯  `as` keyword 
    ╰─────────╯   value-binding pattern 
+0

Это действительно интересно. Я этого не знал. Спасибо! –

0

Swift-Блог:

Проще всего вспомнить шаблон для этих операторов в Swift как:! подразумевает, что «это может ловушка», а? указывает, что «это может быть ноль».

И есть третья возможность гарантированного преобразования, когда происходит сверкание. Для примера 2 as Any получает предупреждение при использовании as! или as?

В случае конструкции переключателя, то case let value as Type: никогда не сможет ни есть возможность, то значение будет дополнительный тип в отличие от выражения value as? Type