【问题标题】:Swift 3.0 Optional ChainingSwift 3.0 可选链
【发布时间】:2016-11-17 02:28:50
【问题描述】:

我是 swift 新手,所以这绝对是一个新手级别的问题。我在思考一些 Swift 3.0 文档时发现了一个潜在的错误。我想知道这个例子是否不正确(或模棱两可),或者我实际上错过了一些指导方针。

请参阅http://swiftdoc.org/v3.0/type/Optional/ 关于可选链接的部分。

可选链

要安全地访问包装实例的属性和方法,请使用后缀可选链接运算符 (?)。以下示例使用可选链接访问 String? 实例上的 hasSuffix(_:) 方法。

if let isPNG = imagePaths["star"]?.hasSuffix(".png") {
    print("The star image is in PNG format")
}
// Prints "The star image is in PNG format"

AFAIU,imagePaths["star"]?.hasSuffix(".png") 仅在imagePaths["star"] 导致Optional.some(wrapped) 时才应该安全地打开imagePaths 并运行hasSuffix()。这意味着isPNG 将是truefalse。因此,上述示例的含义是不正确的,因为它隐含地声称如果 this 安全地展开,则该值始终为 true。

这里有一些例子来解释我在说什么:

if let isPNG = imagePaths["star"]?.hasSuffix(".png") {
    print("The star has png format")
} else {
    print("The star does not have png format")
}

if let isPNG = imagePaths["portrait"]?.hasSuffix(".png") {
    print("The portrait has png format")
} else {
    print("The portrait does not have png format")
}
// "The portrait has png format\n"

if let isPNG = imagePaths["alpha"]?.hasSuffix(".png") {
    print("The alpha has png format")
} else {
    print("The alpha does not have png format")
}
// "The alpha does not have png format\n"

我只是想知道我当前的分析是否有误,或者 SwiftDoc.org 是否需要更改此特定示例。

【问题讨论】:

  • 我同意。文档不正确。该示例的正确版本是if let isPNG = imagePaths["star"]?.hasSuffix(".png") where isPNG { ... }if imagePaths["star"]?.hasSuffix(".png") == true { ... }。但他们的例子是不正确的。
  • ... 或者更具描述性:if let img = imagePaths["star"] where img.hasSuffix(".png") { ... }.
  • 该示例实际上源自 Apple 的文档 developer.apple.com/reference/swift/optional(生成自 github.com/apple/swift/blob/master/stdlib/public/core/…),因此应该有人提交错误报告。

标签: swift


【解决方案1】:

您的分析是正确的,SwiftDoc.org 上的示例至少是 误导,如下代码所示:

let imagePaths = ["star": "image1.tiff"]

if let isPNG = imagePaths["star"]?.hasSuffix(".png") {
    print("The star has png format")
} else {
    print("The star does not have png format")
}

// Output: The star has png format

如果

可选绑定成功
imagePaths["star"]?.hasSuffix(".png")

不是nil,也就是说,如果可以执行可选链接, 即如果imagePaths["star"] != nil.

测试所有情况的正确方法是

if let isPNG = imagePaths["star"]?.hasSuffix(".png") {
    if isPNG {
        print("The star has png format")
    } else {
        print("The star does not have png format")
    }
} else {
    print("No path in dictionary")
}

当然,这可以通过多种方式进行简化(零合并运算符、模式匹配……)。例如

switch(imagePaths["star"]?.hasSuffix(".png")) {
case true?:
    print("The star has png format")
case false?:
    print("The star does not have png format")
case nil:
    print("No path in dictionary")
}

let isPNG = imagePaths["star"]?.hasSuffix(".png") ?? false

(问题的 cmets 中有更多示例。)

【讨论】:

  • 这很有意义。最后的代码是我最后想出的。谢谢。
【解决方案2】:

我相信您将 Optionals 与 Bool 混为一谈。它们并不相同,尽管在某些情况下 nil 表现得像假。

【讨论】:

  • 我解释了来自SwiftDoc.org 的示例,并尝试创建我上面发布的其他示例。我非常有信心我创建的示例是有效的。所以看起来它与原始示例本身以及它试图暗示的内容有关。
猜你喜欢
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 2019-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多