Craig Otis Craig Otis - 1 month ago 4
Swift Question

Creating enums with specific values/stored properties

I have a

CompassDirection
enum that I normally define in Java like so:

enum CompassDirection {
N(0, 1), S(0, -1), E(1, 0), W(-1, 0), NE(1, 1), NW(-1, 1), SE(1, -1), SW(-1, -1)
...


Where the constructor expects
alterX
and
alterY
integer properties, stores them, and uses them in an
alter(Position position)
method like so:

public Position alter(Position pos) {
return new Position(pos.x + this.alterX, pos.y + this.alterY);
}


My goal is to accomplish something similar in Swift. I can easily add an 8-case
switch
statement in my
alter()
method but this tends to add a lot more code and confusion.

This is what I tried in Swift:

enum CompassDirection {
case N(0, 1), S(0, -1), E(1, 0), W(-1, 0), NE(1, 1), NW(-1, 1), SE(1, -1), SW(-1, -1)

private let xAlter : Int
private let yAlter : Int

private init(_ xAlter: Int, _ yAlter: Int) {
self.xAlter = xAlter
self.yAlter = yAlter
}

func alter(position: XYPosition) -> XYPosition {
return XYPosition(x: position.x + self.xAlter, y: position.y + self.yAlter)
}
}


But Swift does not support stored properties in enums.

What is the most readable/Swifty solution for converting the above Java enum to a Swift enum?

Answer

Swift does not support stored properties in enums

You could make xAlter and yAlter computed properties. Here's a highly simplified example (only two cardinal directions):

enum CompassDirection {
    case n
    case s
    var alterX : Int {
        switch self {
        case .n: return 0
        case .s: return 0
        }
    }
    var alterY : Int {
        switch self {
        case .n: return 1
        case .s: return -1
        }
    }
}

Now you can add a method referring to self.alterX and self.alterY, exactly as you desire.

Comments