I've got an enumeration with a few different cases which are different types, e.g.
enum X {
case AsInt(Int)
case AsDouble(Double)
}
I can switch
on these just fine to get the underlying value back out. However, the switch
statement is highly annoying with trying to make me execute some code for the other cases that I simply don't care about. For example, right now I have something like
func AsInt(x: X) -> Int? {
switch x {
case AsInt(let num):
return num;
default:
return nil;
}
}
This works but it's pretty tedious always having to reference this method and having to write a new one for each case of each enumeration. What I'm looking for is how to simply attempt to cast a value of type X
to one of the cases, like
var object: X = func();
let value = obj as? Int;
if value {
// do shit
}
How can I simply check for a case without having to enumerate all of the cases about which I don't care and execute some non-statement for them?
Bonus points for any solution that can declare value
as part of the conditional instead of polluting the scope.
For instance, you might describe a weather enum that lists sunny, windy, and rainy as cases, but has an associated value for cloudy so that you can store the cloud coverage. Or you might describe types of houses, with the number of bedrooms being an associated integer.
In Swift enum, we learned how to define a data type that has a fixed set of related values. However, sometimes we may want to attach additional information to enum values. These additional information attached to enum values are called associated values.
Associated values are set when you create a new constant or variable based on one of the enumeration's cases, and can be different each time you do so.
Although we have said that it can not has stored properties, it can(and in most cases should) has rawValue: meaning of the case in current enum's context. I'm going to demonstrate some cases of usage enums as data model by adding functionality gradually.
There are actually multiple ways to do it.
Let's do it by extending your enum with a computed property:
enum X {
case asInt(Int)
case asDouble(Double)
var asInt: Int? {
// ... see below
}
}
if case
By having let
outside:
var asInt: Int? {
if case let .asInt(value) = self {
return value
}
return nil
}
By having let
inside:
var asInt: Int? {
if case .asInt(let value) = self {
return value
}
return nil
}
guard case
By having let
outside:
var asInt: Int? {
guard case let .asInt(value) = self else {
return nil
}
return value
}
By having let
inside:
var asInt: Int? {
guard case .asInt(let value) = self else {
return nil
}
return value
}
The last one is my personal favorite syntax of the four solutions.
As of Swift 2 (Xcode 7) this is possible with if/case
and
pattern matching:
let x : X = ...
if case let .AsInt(num) = x {
print(num)
}
The scope of num
is restricted to the if-statement.
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