So, I’ve been looking for a solution to this problem for about 2 days. I’ve rummaged the Swift documentation, tried many different google / stack overflow searches, and just straight up randomly wrote code to no avail. I think part of the problem is that I don’t know how to word it... so sorry is this is confusing, but hopefully the code I attached clears it up.
Anyways, I want to know if it’s possible to have a private field in an enum such that each enum value has its own value for this field. I am not asking about extending another class, and I’m not asking about associated values. Unfortunately, I have yet to come across anything online saying whether this is allowed in Swift, and so, how to do it. To highlight my question, I’m trying to recreate the following Java code in Swift:
// Java
public enum Direction {
LEFT(0, -1), RIGHT(0, 1), UP(-1, 0), DOWN(1, 0);
private final int rowChange, colChange;
Direction(int rowChange, int colChange) {
this.rowChange = rowChange;
this.colChange = colChange;
}
public int rowChange() {
return this.rowChange;
}
public int colChange() {
return this.colChange;
}
}
This is what I have at the moment, which works, but I would rather have it have stored values rather than switching through each possible case.
// Swift
public enum Direction {
case left, right, up, down
public func rowChange() -> Int {
switch self {
case .left:
return 0
case .right:
return 0
case .up:
return -1
case .down:
return 1
}
}
public func colChange() -> Int {
switch self {
case .left:
return -1
case .right:
return 1
case .up:
return 0
case .down:
return 0
}
}
}
You can conform to RawRepresentable and use (Int, Int) as Self.RawValue:
enum Direction : RawRepresentable {
case left, right, up, down
var rawValue : (Int, Int) {
switch self {
case .left: return (0, -1)
case .right: return (0, 1)
case .up: return (-1, 0)
case .down: return (1, 0)
}
}
init?(rawValue: (Int, Int)) {
switch rawValue {
case (0, -1): self = .left
case (0, 1): self = .right
case (-1, 0): self = .up
case (1, 0): self = .down
case (_, _): return nil
}
}
var rowChange : Int { return self.rawValue.0 }
var colChange : Int { return self.rawValue.1 }
}
Then you could use it like this:
print(Direction.left.rawValue) // --> (0, -1)
print(Direction.left.rowChange) // --> 0
print(Direction.left.colChange) // --> -1
Switching on self is the standard way. You can have a single value assigned to a enum by letting it inherit from Int (or String is another common case). But for two values like this, the switch would be the normal way.
Maybe consider using a struct instead? Something like this:
struct Direction: Equatable {
let row: Int
let column: Int
static let left = Direction(row: 0, column: -1)
static let right = Direction(row: 0, column: 1)
static let up = Direction(row: -1, column: 0)
static let down = Direction(row: 1, column: 0)
private init() {
// Just to disable empty initialisation, not actually used.
self.row = 0
self.column = 0
}
private init(row: Int, column: Int) {
self.row = row
self.column = column
}
}
And it can be accessed like this:
let direction = Direction.left
let row = direction.row
let column = direction.column
Also, if the goal is to use pattern matching, it's possible when the struct inherits from Equatable allowing you to write something like:
switch direction {
case .left:
break
case .right:
break
case .up:
break
case .down:
break
default:
break
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With