简体   繁体   中英

“Raw value for enum case is not unique” for Swift enum with Float raw values

According to The Swift Programming Language , I should be able to create a Swift enum with raw values of "strings, characters, or any of the integer or floating-point number types". But when I try:

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

... I get a compilation error:

Raw value for enum case is not unique

on the v7v4 line. It compiles fine with that one commented out. But ah, it looks unique to me. If I make the value 7.41, or 7.3 or something else it compiles fine. What's going on? Swift bug?

It definitely says you can , but don't use floating-point values (and especially Float ) where you're going to need to compare equality -- the precision just isn't guaranteed to be good enough. And always use Double unless you absolutely need to use a Float for compatibility reasons.

In this case, it seems like it's having trouble because (a) the third case is 2x the first case, and (b) some other factor I don't know. Using 3.3/6.6 , 3.4/6.8 , and 3.6/7.2 also gave me the issue, but 3.5/7.0 did not. However, I could get it to show up by changing the last case to 22.2 (2x 11.1 ).

Here's a workaround — use a typical Int -based enumeration, and provide a doubleValue property:

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
        }
    }
}

There are some nice additional features of enums you can take advantage of if they're Int -based.

(From my above comment:)

That looks definitely like a bug. It seems to happen if one enum value is exactly equal to "2 times another enum value", but not equal to an integer.

More generally (as @Sulthan observed) the error occurs if the ratio of the enumeration values is a power of two , such as 3.7/7.4 , 1.2/4.8 , or 1.1/17.6 , but only if both values have a non-zero fractional part. So 1.5/3.0 or 1.25/5.0 do not cause an error.

For me this is worked.

I was assigning empty string to multiple case values in the enum. I changed that. Make sure every case value is unique.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM