Need clarification of Type Casting operator in Swift

北战南征 提交于 2020-01-05 02:54:05

问题


Why is the type cast operator (as) being used instead of its conditional form (as?) in this switch statement?

I thought the type operator could only be (as?) or (as!)...? The Apple Swift documentation does not provide adequate explanation about this.

Here is the example in the Swift documentation:

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")
        }
    }

Here is the link to the Apple Swift documentation on Type Casting


回答1:


You could have found the answer yourself if you read the note on the bottom:

The cases of a switch statement use the forced version of the type cast operator (as, not as?) to check and cast to a specific type. This check is always safe within the context of a switch case statement.

(emphasis mine)

Here is an Apple blog post which elaborates on the difference between as?, as and as!.




回答2:


The as in case 0 as Int: or case let someInt as Int: is part of a type casting pattern. In the Swift Language Reference the case label of a switch statement is defined as

case-labelcase ­case-item-list­:
­case-item-list → pattern ­guard-clause­opt |­ pattern­ guard-clause­­opt­ , ­case-item-list­

where pattern can be (among other cases)

pattern → value-binding-pattern­
pattern → type-casting-pattern­
pattern → expression-pattern­

and a type casting pattern is

type-casting-pattern → is-pattern­ | as-pattern­
is-patternis ­type­
as-pattern → pattern­ as ­type­

So you have for example

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



回答3:


Swift-Blog:

It may be easiest to remember the pattern for these operators in Swift as: ! implies “this might trap,” while ? indicates “this might be nil.”

And there is the third possibility of a guaranteed conversion, when an upcast is done. For example 2 as Any gets a warning when used with as! or as?

In case of the switch construct, the case let value as Type: never fails nor is there the possibility, that value will be an optional type in contrast to the expression value as? Type



来源:https://stackoverflow.com/questions/31759778/need-clarification-of-type-casting-operator-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!