【问题标题】:Why does sorting array of enums with Swift 5 give different results?为什么使用 Swift 5 对枚举数组进行排序会给出不同的结果?
【发布时间】:2019-03-28 19:40:24
【问题描述】:

我不知道这是一个错误还是一个功能,但是对枚举数组进行排序会在每次运行时给出不同的结果。这是测试它的基本代码。

enum Tag: String {
    case bold, italic, underline
}

extension Tag: Comparable {
    static func <(lhs: Tag, rhs: Tag) -> Bool {
        return lhs.hashValue < rhs.hashValue
    }
}

let tags:[Tag] = [.bold, .italic, .underline].sorted()
print(tags.map {$0.rawValue})

【问题讨论】:

  • @VatsalManot 对。我没注意。我会删除我的评论。
  • @Meanteacher 这里的答案具有误导性:hashValue 是基于函数的。对于给定值的含义,它的 hashValue 将是相同的。除非您存储它,然后稍后在不同的时间再次构建它。从共享链接中,它说“随机播种”意味着 hashValue 属性将在每次执行 Swift 程序时返回 不同的值。 即它不会在 Xcode 构建“期间”发生变化。除此之外:基于它们的字符串原始值比较枚举是不正确的。你如何比较“john”、“Peter”和“TJ”? OP 没有说明他希望如何比较它们......

标签: swift swift5


【解决方案1】:

简单的答案:

在您的示例中,您正在使用String 的hashValue 进行比较。 Swift 5 的哈希算法与 Swift 4 不同。

您正在寻找的答案:

不要根据哈希值对字符串(或任何类型)进行排序,这不是您要查找的内容。你要找的是this。

你想要的实现大概是这样的:

extension Tag: Comparable {
    static func <(lhs: Tag, rhs: Tag) -> Bool {
        return lhs.rawValue < rhs.rawValue
    }
}

rawValue 是枚举的原始 String 值。

哈希值是hash function 的乘积,与排序完全无关。

奖励信息:

对于那些想知道为什么每次 Swift 运行的哈希值都不同的精明观察者,here 是个问题。

【讨论】:

  • 很高兴知道为什么哈希每次都不同,这是冲突吗?
  • @Alex Swift 的标准库哈希函数现在在每次程序执行时使用随机种子(如 here 所讨论的)。
  • "你想要的实现大概是这样的:"你为什么不问他?通常你不想比较“Alex”和“TJ”。
【解决方案2】:

很确定是因为this:

不保证哈希值在不同的执行中是相等的 你的程序。不要保存哈希值以供将来使用 执行。

如果您将比较方法更改为:

return lhs.rawValue < rhs.rawValue

应该可以。

【讨论】:

  • hashValue 基于函数。对于给定值的含义,它的 hashValue 将是相同的。除非您存储它,然后稍后在不同的时间再次构建它。从共享链接中,它说“随机播种”意味着 hashValue 属性将在每次执行 Swift 程序时返回 不同的值。 即它不会在 Xcode 构建“期间”发生变化。除此之外:基于它们的字符串原始值比较枚举是不正确的。你如何比较“john”、“Peter”和“TJ”? OP 没有说明他希望如何比较它们......
  • @Honey 我正在寻找确定性顺序。我了解到 hashValue 不是确定性的。这个答案对我的用例来说已经足够了。
  • @Honey 你能帮我去掉那个-1吗,老兄?
  • @leahyjwilliam 我给了你 +1 并接受了你的回答。我不知道谁给了你-1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 2021-07-28
相关资源
最近更新 更多