【问题标题】:Need clarification of Type Casting operator in Swift需要澄清 Swift 中的类型转换运算符
【发布时间】:2024-04-27 18:05:02
【问题描述】:

为什么在这个 switch 语句中使用类型转换运算符 (as) 而不是条件形式 (as?)?

我认为类型运算符只能是 (as?) 或 (as!)...? 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的链接

【问题讨论】:

标签: swift casting typecasting-operator


【解决方案1】:

Swift 博客:

在 Swift 中,这些运算符的模式可能最容易记住:!暗示“这可能会陷入陷阱”,而 ?表示“这可能为零。”

当向上转换完成时,还有第三种保证转换的可能性。例如2 as Anyas!as? 一起使用时会收到警告

在 switch 构造的情况下,case let value as Type: 永远不会失败,也不存在这种可能性,与表达式 value as? Type 相比,该值将是可选类型

【讨论】:

    【解决方案2】:

    case 0 as Int:case let someInt as Int: 中的 as 是其一部分 类型转换模式。在Swift Language Reference switch 语句的 case 标签中 被定义为

    case-labelcase case-item-list:
    case-item-list → 模式保护子句opt | 模式保护子句opt , case-item-list

    模式可以在哪里(在其他情况下)

    模式 → 值绑定模式
    模式 → 类型转换模式
    模式 → 表达式模式

    类型转换模式是

    type-casting-pattern → is-pattern | as-pattern
    is-patternis 类型
    as-pattern → 模式 as 类型

    所以你有例如

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

    【讨论】:

    • 这真的很有趣。我不知道这个。谢谢!
    【解决方案3】:

    如果您阅读底部的note,您可能已经找到了答案:

    switch 语句的情况使用强制版本的类型转换运算符(as,而不是 as?)来检查并转换为特定类型。在 switch case 语句的上下文中,此检查始终是安全的。

    (强调我的)

    Here 是 Apple 的一篇博文,详细阐述了 as?asas! 之间的区别。

    【讨论】:

    • 同一份文档还在文档中的许多不同位置将“类型转换运算符的强制版本”称为“(as!)”,因此我可以理解沃尔特的困惑。
    • 是的,我已阅读该说明。该注释说“类型转换运算符的强制版本”,即 a!。它没有解释为什么不包括感叹号(!)。此外,您的参考资料解释说 as 是有保证的转换。我不确定那是什么意思。 Swift 文档只解释了 as?as!
    • 该!不包括在内,因为永远不会发生运行时错误 - case 声明 保证 如果 thing 不是 Int,则不执行转换。不过,我同意你的观点。
    • @Glorfindel 谢谢!这就是我想知道的:)。在我看来,Apple 使这份文档过于简洁,以至于最终让像我这样的人感到疑惑。感谢您花时间回答我的问题:)
    最近更新 更多