'Enum variables in Swift?

I would like to associate multiple values with an enum value, in a generic way.

This can be done in Java:

enum Test {

    A("test", 2);

    final String var1;
    final int var2;

    Test (String var1, int var2) {
        this.var1 = var1;
        this.var2 = var2;
    }
}

 public static void main(String []args){
    Test test = Test.A;
    System.out.println(test.var1);
 }

But it looks like it's not possible with Swift? So far, according to docs, there are:

  1. Associated values. Example (from docs):

    enum Barcode {
        case UPCA(Int, Int, Int, Int)
        case QRCode(String)
    }
    

    But this is not what I need.

  2. Raw value. Example (from docs):

    enum ASCIIControlCharacter: Character {
        case Tab = "\t"
        case LineFeed = "\n"
        case CarriageReturn = "\r"
    }
    

    This would be what I need, but it can have only one value!

Is there an elegant solution for this...? Seems like a language design decision, as it would conflict with the associated values concept, at least in the current form. I know I could use e.g. a dictionary to map the enum values to the rest, but really missing to do this in one safe step, like in Java.



Solution 1:[1]

Yes it is a design decision but you can kind of work around it in some cases. The idea is to extend a Type to conform to one of: integer-literalĀ­ floating-point-literalĀ­ string-literal

The solution can be found here Bryan Chen's solution: How to create enum with raw type of CGPoint?

The second solution presented there by Sulthan may also be a way to go for you.

Solution 2:[2]

I'm not familiar enough with Swift's history to know if this was possible back when the question was asked. But this is what I would do today in Swift 5.x:

enum Direction {
    case north
    case east
    case south
    case west

    func name() -> String {
        switch self {
        case .north: return "North"
        case .east: return "East"
        case .south: return "South"
        case .west: return "West"
        }
    }

    func degress() -> Double {
        switch self {
        case .north: return 0.0
        case .east: return 90.0
        case .south: return 180.0
        case .west: return 270.0
        }
    }
}

It retains all the benefits of Swift enums, chief of all, IMO, the ability for the compiler to infer when your code is exhaustive when pattern matching.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Jack Leow