Enumeration with Raw Values

How to get enum from raw value in Swift?

Too complicated, just assign the raw values directly to the cases

enum TestEnum: String {
case Name = "Name"
case Gender = "Gender"
case Birth = "Birth Day"
}

let name = TestEnum(rawValue: "Name")! //Name
let gender = TestEnum(rawValue: "Gender")! //Gender
let birth = TestEnum(rawValue: "Birth Day")! //Birth

If the case name matches the raw value you can even omit it

enum TestEnum: String {
case Name, Gender, Birth = "Birth Day"
}

In Swift 3+ all enum cases are lowercased

Enumeration with raw values

Because:

Raw values can be strings, characters, or any of the integer or floating-point number types.

But there is an alternative solution for you:

enum Edges {
case TopLeft
case TopRight
case BottomLeft
case BottomRight

func getTuple() -> (Double, Double) {
switch self {
case .TopLeft:
return (0.0, 0.0)
case .TopRight:
return (1.0, 0.0)
case .BottomLeft:
return (0.0, 1.0)
case .BottomRight:
return (1.0, 1.0)
}
}
}

let a = Edges.BottomLeft
a.getTuple() // returning (0, 1)

How could I use the multiple Enum raw values of type Int in Swift?

Enum cases can not have multiple rawValues. Becase imagine you call this:

print( STATUS_CODE.onGoing.rawValue )

What value you expect to be printed?


Instead you can have a custom enum like the one you think of:

enum STATUS_CODE: RawRepresentable {

init(rawValue: Int) {
switch rawValue {
case 5, 50,70, 90: self = .onGoing(rawValue)
case 10: self = .atWorkshop
case 16: self = .completed
case 35: self = .comedy
case 80: self = .crime
case 0: self = .NoDate

default: self = .unknown(rawValue)
}
}

var rawValue: Int {
switch self {
case .onGoing(let rawValue): return rawValue
case .atWorkshop: return 10
case .completed: return 16
case .comedy: return 35
case .crime: return 80
case .NoDate: return 0
case .unknown(let rawValue): return rawValue
}
}

case onGoing(Int)
case atWorkshop
case completed
case comedy
case crime
case NoDate

case unknown(Int)

func getString() -> String {
switch self {
case .onGoing : return "New order"
case .atWorkshop: return "At workshop"
case .completed : return "Animation"
case .comedy : return "Comedy"
case .crime : return "Crime"
case .NoDate : return "No Order"

case .unknown(let rawValue): return "Unknown \(rawValue)"
}
}
}

ofcourse it is a demo and can be refactored ;)

Can a Swift enum have a function/closure as a raw value?

It's not as straight forward, but you could use OptionSet, see this page:

Unlike enumerations, option sets provide a nonfailable init(rawValue:) initializer to convert from a raw value, because option sets don’t have an enumerated list of all possible cases. Option set values have a one-to-one correspondence with their associated raw values.

Could be something like this:

func doSomething() {}
func doSomethingElse() {}

struct MyClosures: OptionSet {

static let closureOne = MyClosures(rawValue: doSomething)
static let closureTwo = MyClosures(rawValue: doSomethingElse)

let rawValue: () -> Void

init(rawValue: @escaping () -> Void) {
self.rawValue = rawValue
}

init() {
rawValue = {}
}

mutating func formUnion(_ other: __owned MyClosures) {
// whatever makes sense for your case
}

mutating func formIntersection(_ other: MyClosures) {
// whatever makes sense for your case
}

mutating func formSymmetricDifference(_ other: __owned MyClosures) {
// whatever makes sense for your case
}

static func == (lhs: MyClosures, rhs: MyClosures) -> Bool {
// whatever makes sense for your case
return false
}
}

And so you can use it as:

let myClosures: MyClosures = [ .closureOne, .closureTwo ]

HOWEVER looking at your explanation in the comment:

So I'm trying to find the most efficient way to run a function given the state of a variable.

I think what you actually want is some sort of state machine. Some examples are available here and here

Enumerations in C++ with raw values?

I must admit that I don't know anything about Swift except its name.

In C++, strings may not be used in enumerations.

Enumeration Declaration:

An enumeration is a distinct type whose value is restricted to a range of values (see below for details), which may include several explicitly named constants ("enumerators"). The values of the constants are values of an integral type known as the underlying type of the enumeration.

(Emphasize mine.)

What might work:

enum AnOperations: char {
Addition = '+',
Subtraction = '-',
Division = '/'
};

because char is one of the integral types.

Sample:

#include <iostream>
#include <sstream>

int main()
{
enum AnOperations: char {
Addition = '+',
Subtraction = '-',
Division = '/'
};
std::string text = "1 + 2";
std::istringstream in(text);
int arg1, arg2, result; char op;
in >> arg1 >> op >> arg2;
switch (op) {
case Addition: result = arg1 + arg2; break;
case Subtraction: result = arg1 - arg2; break;
case Division: result = arg1 / arg2; break;
default:
std::cerr << "Unknown op. '" << op << "'!\n";
return 1;
}
std::cout << arg1 << ' ' << op << ' ' << arg2 << " = " << result << '\n';
return 0;
}

Output:

1 + 2 = 3

Live Demo on coliru

Difference between associated and raw values in swift enumerations

Raw values are for when every case in the enumeration is represented by a compile-time-set value. The are akin to constants, i.e.

let A = 0
let B = 1

is similar to:

enum E: Int {
case A // if you don't specify, IntegerLiteralConvertible-based enums start at 0
case B
}

So, A has a fixed raw value of 0, B of 1 etc set at compile time. They all have to be the same type (the type of the raw value is for the whole enum, not each individual case). They can only be literal-convertible strings, characters or numbers. And they all have to be distinct (no two enums can have the same raw value).

Associated values are more like variables, associated with one of the enumeration cases:

enum E {
case A(Int)
case B
case C(String)
}

Here, A now has an associated Int that can hold any integer value. B on the other hand, has no associated value. And C has an associated String. Associated types can be of any type, not just strings or numbers.

Any given value of type E will only ever hold one of the associated types, i.e. either an Int if the enum is an A, or a String if the enum is a C. It only needs enough space for the bigger of the two. Types like this are sometimes referred to as "discriminated unions" – a union being a variable that can hold multiple different types, but you know (from the enum case) which one it is holding.

They can even be generic. The most common example of which is Optional, which is defined like this:

enum Optional<T> {
case .Some(T)
case .None
}

How to get the name of an enumeration case by its raw value in Swift 4?

You can't get the case name as as String as the enum's type isn't String, so you'll need to add a method to return it yourself…

public enum TestEnum: UInt16, CustomStringConvertible {
case ONE = 0x6E71
case TWO = 0x0002
case THREE = 0x0000

public var description: String {
let value = String(format:"%02X", rawValue)
return "Command Type = 0x" + value + ", \(name)"
}

private var name: String {
switch self {
case .ONE: return "ONE"
case .TWO: return "TWO"
case .THREE: return "THREE"
}
}
}

print(TestEnum.ONE)

// Command Type = 0x6E71, ONE


Related Topics



Leave a reply



Submit