【问题标题】:Casting removes all levels of Optional in Swift?Casting 删除了 Swift 中所有级别的 Optional?
【发布时间】:2018-09-24 18:13:04
【问题描述】:

我们都知道你可以使用可选绑定来解开一个可选的:

let b: String? = "bye"

if let greeting = b {
    print(greeting)  // "bye"
}

但如果该值有多个级别的可选项,则只会删除一个:

let b: String?? = "bye"
if let greeting = b {
    print(greeting)  // "Optional(bye)"
}

将值转换为基础类型将删除双重可选:

let b: String?? = "bye"
if let greeting = b as? String {
    print(greeting)  // "bye"
}

我惊讶地发现这适用于任何级别的选项:

let b: String??????? = "bye"
print(b as Any)  // Optional(Optional(Optional(Optional(Optional(Optional(Optional("bye")))))))

if let greeting = b as? String {
    print(greeting)  // "bye"
}

是否解释了为什么强制转换会删除所有级别的选项?

还有:

let b: String??????? = "bye"
print(b as! String)  // "bye"

但它给出了幽默的警告:

从 'String???????' 强制转换仅解开选项;你的意思是使用'!!!!!!!'。

【问题讨论】:

  • 是使用 Foundation 导入还是纯 Swift?
  • @Sulthan,纯 Swift 具有相同的行为。
  • 您考虑过在forums.swift.org/c/swift-users 上提问吗?
  • Swift 的运行时强制转换机制可以查看可选值以(递归地)对有效负载值执行强制转换(实际上是 the very first thing it tries to do)。
  • 基本上它已融入语言。如果您考虑一下,铸造 Optional 根本不应该是合法的,但它得到了一个特殊的幕后授权来允许它。我不喜欢语法糖,Swift 值得注意的是要避免它,但 Optionals 的强制转换无疑是一个很好的例子。

标签: swift casting optional


【解决方案1】:

这是因为在结构if let unwrapped = instance as? Type 中,首先评估右侧部分。完整的订单是

  1. Swift 尝试通过执行 instance as? Type 将实例转换为 Typeas? 运算符始终执行以下操作 - 如果 instance 可以表示为 Type,则将其强制转换,否则返回 nil。重要的部分是as? Type 运算符始终返回Optional<Type>,无论instance 的类型如何。

  2. if let 运算符,始终只展开一层,将这个 Optional<Type> 展开为 Type

【讨论】:

  • 当然,但另一个选项是让as? 返回nil,因为起始值不是Optional<String>。让我感到惊讶的是 Swift 确实决定 String??????? 可以转换为 String
  • 是的,但是你的代码不是检查 b 是可选的,你只是检查 b 可以表示为字符串,我相信所有级别的 Optional>> 可以转换为 String,如果它们包含一个值。
  • 显然所有级别的 Optional>> 都可以转换为 String。这对我来说是一个令人惊讶的结果,自从 Swift 首次出现在测试版中以来,我一直在关注它。我想知道这是否记录在任何地方。
猜你喜欢
  • 2022-01-13
  • 2017-02-13
  • 2012-06-07
  • 1970-01-01
  • 2014-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
相关资源
最近更新 更多