Swift 类型转换/向下转换

Swift type casting / downcasting

为什么Xcode创建的Sprite Kit Game模板项目使用as!:

if let sceneNode = scene.rootNode as! GameScene? {...}

下面的不是同样好吗?

if let sceneNode = scene.rootNode as? GameScene {...}

请注意,这不是标准 "what is the difference between as? and as!" 问题。 Downcasting optionals in Swift: as? Type, or as! Type? 非常接近,但也不完全相同。问题是上面的两个模式在功能上看起来很相似(它们都是 downcast 和 unwrap),但不清楚为什么作者使用 if let ... as! GameScene? { ... } 而不是更常见和更自然的 if let ... as? GameScene { ... }.

我会说这是一个错误。在任何情况下,模式 if let x = y as! Type? 都是不必要的,您不应该模仿它。模式 if let x = y as? Type 是等价的并且通常。

这两种模式非常接近,但在技术上并不相同:

  • if let ... as! GameScene? {...} 强制转换为 GameScene?,然后 if let 安全地解包结果可选值。

  • if let ... as? GameScene { ... } 将优雅地向下转换并展开结果。

这两个在功能上几乎是等价的。问题是为什么模板会使用以前的语法。有人可能会争辩说 as? 模式有点模棱两可,因为看一眼代码你就无法判断你是否只是在测试一个向下转换的成功,或者你是否也在处理一个可选的。模板的代码使这一点更加明确。

综上所述,我会使用 if let ... as? GameScene { ... } 模式。这是惯例。