2

When I have a situation where I already know enum case statement I want to get the associated value of, is there a cleaner way than using a switch statement to pluck out the associated value?

To have to come up with a switch statement, provide multiple cases, or a default case just to extract the associated value is gaudy.

enum CircularReasoning {
    case justPi(pi: Double)
    case pizzaPie(howMany: Int)
}

var piInTheSky : Double 

let whatLogic = CircularReasoning(pi: 3.1415926)

⬇️    ⬇️ 

switch whatLogic {
    case .justPi(let pi):
        piInTheSky = pi!
    default:
        break
}
clearlight
  • 12,255
  • 11
  • 57
  • 75

2 Answers2

2

You can use if case .<enum_case>(let value) as in TylerP's example, or if case let .<enum_case>(value):

enum Foo {
    case anInt(Int)
    case aFloat(Float)
}

let aFoo: Foo = .anInt(9)

// Example of `if case .<enum_case)(let value)` syntax:
if case .anInt(let aValue) = aFoo {
    print("aFoo = anInt(\(aValue))")

// Example of `if case let .enum_case(value)` syntax:
} else if case let .aFloat(aValue) = aFoo {
    print("aFoo = aFloat(\(aValue))")
}

Both work. I'm not sure why the language includes both variants.

If you only care about one enum type, then either if syntax makes sense to me. If you are dealing with more than one possible enum value then the switch version seems cleaner.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • I totally agree switch is cleaner for multiples, but in my case the way I'm setting up a parser, I have many cases where I would only have a switch with one case statement to extract one associated value set, in lieu of your answer. Thank you. – clearlight Aug 07 '22 at 23:41
0

Here's an adaptation of @DuncanC's excellent upvoted and accepted answer, as applied to a fictitious version of my real-world use case.

It illustrates a possible way to use his answer to reduce the space required to extract associated values, especially if one has a lot of one-off cases...

Note: Not implying this is appropriate or professional swift styling; it's clearly idiosyncratic, yet compact. (I usually don't compress things into one liners like this, unless they get really repetitive/redundant & produce lot of pointless vertical bloat).

enum RealmKey { case realmOfRealms, anyOldRealm, someOtherRealm }
.
.
.
enum SymbolToken {
    case realm       (key: RealmKey?)
    case space       (key: SpaceKey?)
    case area        (key: AreaKey?)
    case region      (key: RegionKey?)
    case preserve    (key: PeserveKey?)
    case openParen
    case closeParen
    case logicalAnd
    case logicalOr
    case logicalNot
    
    var realmKey    : RealmKey?    { if case .realm    (let key) = self { return key } else { return nil } }
    var spaceKey    : SpaceKey?    { if case .space    (let key) = self { return key } else { return nil } }
    var areaKey     : AreaKey?     { if case .area     (let key) = self { return key } else { return nil } }
    var regionKey   : RegionKey?   { if case .region   (let key) = self { return key } else { return nil } }
    var preserveKey : PreserveKey? { if case .preserve (let key) = self { return key } else { return nil } }
}

let realm = SymbolToken.realm(.realmOfRealms)
let realmKey = realm.realmKey
clearlight
  • 12,255
  • 11
  • 57
  • 75