3

I've run into an issue with my enums in that I want to initialize a case to the double value of PI / 180. Is there a way to take this calculated value via a constant or some funky magic and turn it into a literal so that I can initialize the enum?

I would prefer not to have to do a 3.14.... - I would rather use the actual compiler and hardware computed representation of this value.

So my 1st attempt was:

public enum ANGLE_TYPE : Double {

    case DEGREES = Double(CGFloat(M_PI / 180.0))
    case RADIANS = 1.0
}

I keep getting the error Raw value for enum case must be a literal

Second attempt was :

public enum ANGLE_TYPE : Double {
  let d : Double = Double(CGFloat(M_PI / 180.0))

case DEGRESS = d
}

and i get the same error.

Could somebody please tell me how to go about doing this.

Jeef
  • 26,861
  • 21
  • 78
  • 156

1 Answers1

11

You can only use literals for the raw values of type-backed enums.

To get this to work, you have to calculate the raw value of the calculation you're performing and paste that literal in as an approximation:

public enum ANGLE_TYPE : Double {
    case DEGREES = 0.0174532925199433
    case RADIANS = 1.0
}

The only other option is to not have a type-backed enum and manually provide the rawValue property:

public enum ANGLE_TYPE {
    case DEGREES, RADIANS

    var rawValue: Double {
        get {
            switch self {
            case .DEGREES:
                return Double(CGFloat(M_PI / 180.0))
            case .RADIANS:
                return 1.0
            }
        }
    }
}

This might make sense because this means you don't have the init(rawValue:Double) initializer, which doesn't make a whole lot of sense in this case probably.

As a side note, this all caps thing is really unnecessary. I'd much prefer something more like this:

public enum AngleMeasureUnit {
    case Degrees, Radians
}
nhgrif
  • 61,578
  • 25
  • 134
  • 173