【问题标题】:"Raw value for enum case is not unique" for Swift enum with Float raw values带有浮点原始值的 Swift 枚举的“枚举大小写的原始值不是唯一的”
【发布时间】:2014-11-04 16:12:35
【问题描述】:

根据The Swift Programming Language,我应该能够使用“字符串、字符或任何整数或浮点数类型”的原始值创建一个 Swift 枚举。但是当我尝试时:

enum BatteryVoltage: Float {
    case v3v7 = 3.7
    case v5v0 = 5.0
    case v7v4 = 7.4
    case v11v1 = 11.1
    case v12v0 = 12.0
}

...我得到一个编译错误:

Raw value for enum case is not unique

在 v7v4 线上。它与注释掉的那个编译得很好。但是啊,它看起来对我来说很独特。如果我将值设为 7.41、7.3 或其他值,它编译得很好。这是怎么回事? Swift 错误?

【问题讨论】:

  • 这看起来绝对像一个错误。如果一个枚举值恰好等于“另一个枚举值的 2 倍”(但不是整数),这似乎会发生。
  • 你知道吗,你是对的。回答您的评论,我会接受。 (并归档雷达。叹息。)
  • 我猜这可能与浮点数的二进制表示有关。也许枚举的相等比较会截断一些位。
  • 雷达归档,rdar://18878723
  • 现在在 Swfit 2 中,这不是错误。

标签: swift enums


【解决方案1】:

它肯定说你可以,但不要使用浮点值(尤其是Float),因为你需要比较相等性——精度不是保证足够好。并且始终使用Double,除非出于兼容性原因绝对需要使用Float

在这种情况下,它似乎遇到了麻烦,因为 (a) 第三种情况是第一种情况的 2 倍,以及 (b) 其他一些我不知道的因素。使用3.3/6.63.4/6.83.6/7.2 也给了我这个问题,但3.5/7.0 没有。但是,我可以通过将最后一个大小写更改为 22.2 (2x 11.1) 来显示它。

这是一种解决方法 - 使用典型的基于 Int 的枚举,并提供 doubleValue 属性:

enum BatteryVoltage: Int {
    case v3v7
    case v5v0
    case v7v4
    case v11v1
    case v12v0

    var doubleValue: Double {
        switch self {
        case .v3v7: return 3.7
        case .v5v0: return 5.0
        case .v7v4: return 7.4
        case .v11v1: return 11.1
        case .v12v0: return 12.0
        }
    }
}

如果它们是基于Int 的,您可以利用一些nice additional features of enums

【讨论】:

  • 我给你这个博客文章链接 - 向枚举添加一个使用 Int 值索引到值数组的方法是实现我想做的更好的方法.
【解决方案2】:

(来自我上面的评论:)

这看起来绝对像一个错误。如果一个枚举值恰好等于“另一个枚举值的 2 倍”,但不等于整数,这似乎会发生。

更一般地(正如@Sulthan 观察到的)如果枚举的比率发生错误 values 是 2 的幂,例如 3.7/7.41.2/4.81.1/17.6,但只有 如果两个值都具有非零小数部分。所以1.5/3.01.25/5.0 不要 导致错误。

【讨论】:

  • @Sulthan:你是对的,不仅因素 2 会导致问题,还有 4、8、16、...
【解决方案3】:

对我来说这是可行的。

我将空字符串分配给枚举中的多个 case 值。我改变了那个。确保每个 case 值都是唯一的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2015-02-26
    相关资源
    最近更新 更多