【问题标题】:Ambiguous use of subscript in Xcode 10.2Xcode 10.2 中下标的模糊使用
【发布时间】:2019-04-09 01:37:53
【问题描述】:

我有一个 Swift 项目,其中我在任何 Collection 类型上使用了 2 个扩展。它们允许安全访问数组中的元素。以下是扩展名:

subscript (safe index: Index) -> Element? {
    return indices.contains(index) ? self[index] : nil
}

subscript (safe int: Int) -> Element? {
    let index = self.index(self.startIndex, offsetBy: int)
    return self[index]
}

这很好用,但在 Xcode 10.2 中现在存在编译器错误。

我试图尽可能明确地说明下标中的类型和元素的类型,但没有奏效。

有人知道为什么这不再起作用了吗?

【问题讨论】:

  • 显示足够的代码,以便其他人可以复制并粘贴到 Playground 并重现问题。

标签: arrays swift xcode swift-extensions


【解决方案1】:

我无法解释为什么这在以前版本的 Xcode 中确实有效,但你不认为你的两个 subscript(safe:) 在 Collection.Index == Int 时足够模棱两可吗?

而且,对于您的第二个subscript(safe:),safe 这个词似乎不合适,因为当int 超出集合范围时,它可能很容易使您的应用崩溃。

extension Collection {
    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }

    subscript (safe int: Int) -> Element? {
        let index = self.index(self.startIndex, offsetBy: int)
        return self[index]
    }
}
var arr: [String] = ["a"]
print(arr[safe: 1])

导致Thread 1: Fatal error: Index out of range上线return self[index]。 (使用 Xcode 10.1 测试。)

第二个subscript 最好使用除safe 之外的另一个词,而这两个subscript 在任何版本的Xcode 中都不会有歧义。

extension Collection {
    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }

    subscript (offsetBy int: Int) -> Element? {
        let index = self.index(self.startIndex, offsetBy: int)
        return self[index]
    }
}

也许我需要澄清我的意图。 (感谢内特。)

您可以将第二个下标设为safe:

extension Collection {
    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }

    subscript (offsetBy int: Int) -> Element? {
        let index = self.index(self.startIndex, offsetBy: int)
        return self[safe: index]
    }
}

即使在这种情况下,您最好为两个 subscript 声明使用不同的标签以避免歧义。

【讨论】:

  • 我觉得offsetBy版本应该使用安全的方法,传递你创建的索引而不是直接调用[]。这将有助于解决越界问题,对吧?
  • @Nate,我认为改进定义的方法不是这个线程的主要关注点,但我不明白你所说的安全方法,你的意思是使用self[safe: index] 而不是 self[index]?
  • 我不熟悉subscript。这就是你在 Swift 中定义 [] 方法调用的方式吗? (我是 Swift 新手,但对编程并不陌生。)如果是这样,那么是的,这就是我的意思。我想我会提到它,因为你指出了崩溃。不过,我可能错过了你提出的观点。
  • 这就是你在 Swift 中定义 [] 方法调用的方式吗? 是的。您的评论与一般编程主题一样具有建议性,但不如 Swift 编程中的评论那么有用。除非您使用 safe 功能定义 subscript,否则 Collection.subscript 可能会崩溃。
  • 这些都是非常有效的观点。正如@OOPer 提到的,第二个下标确实缺少保险箱。谢谢你指出这一点。我认为这两个扩展因类型而异,Swift 可以根据类型确定选择哪一个:myArray[safe: index] 和 myArray[safe: int] 我认为差异很大。或者至少它是在以前版本的 Xcode 中......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多