How to Access a Swift Enum Associated Value Outside of a Switch Statement

How to access a Swift enum associated value outside of a switch statement

As others have pointed out, this is now kind of possible in Swift 2:

import CoreGraphics

enum Line {
case Horizontal(CGFloat)
case Vertical(CGFloat)
}

let min = Line.Horizontal(0.0)
let mid = Line.Horizontal(0.5)
let max = Line.Horizontal(1.0)

func doToLine(line: Line) -> CGFloat? {
if case .Horizontal(let value) = line {
return value
}
return .None
}

doToLine(min) // prints 0
doToLine(mid) // prints 0.5
doToLine(max) // prints 1

Swift get associated value in enums without switch

You could add a property to your enum that returns the protocol. For example:

enum RetailDemandReturnOperation {
case salesReturn(value: MSRetailSalesReturnRealm)
case demand(value: MSRetailDemandRealm)

var realm: MSRetailRealm {
switch self {
case .salesReturn(let realm):
return realm
case .demand(let realm):
return realm
}
}
}

Then, when you want to access those properties on a specific value of the enum, just use:

let operation = RetailDemandReturnOperation.salesReturn(value: MSRetailSalesReturnRealm())
let title = operation.realm.title

access swift enum case outside of switch?

As far as I know, Swift does not provide us a shortcut to retrieve only case labels.

In your case you can write something like this utilizing your name property:

extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
switch (a, b) {
case (.dog, .dog), (.cat, .cat):
return a.name == b.name
default:
return false
}
}
}

If your Pet does not have the name property, you can write it as:

extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
switch (a, b) {
case let (.dog(namea), .dog(nameb)),
let (.cat(namea), .cat(nameb)):
return namea == nameb
default:
return false
}
}
}

But in your case, isn't it sort of natural to use class hierarchy?:

class Pet {
var name: String
init(name: String) {
self.name = name
}
}

class Dog: Pet {}
class Cat: Pet {}

extension Pet {
static func dog(name: String) -> Pet {
return Dog(name: name)
}
static func cat(name: String) -> Pet {
return Cat(name: name)
}
}

extension Pet: Equatable {
static func == (a: Pet, b: Pet) -> Bool {
return type(of: a) === type(of: b) && a.name == b.name
}
}

Extract associated value from enum regardless of the case in Swift

Your code for extracting the associated value from multiple enums is the most economical and easy-to-read, there's no need to improve it.

However, the fact that you are looking to extract an associated value regardless of enum's case suggests that you are not using associated values correctly: rather than associating a value with each individual case, you should create a composite type that holds the Int and an enum without an associated value, i.e.

enum Test {
case a, b, c
}
class MyClass {
var num : Int
var tst : Test
}

Now that the associated value is "outside" each enum element, it can be accessed independently of the case, and you can also give it a meaningful name, which adds to readability of your program.

How to get a swift enum's associated value regardless of the enum case

Define a method isMissing() inside the enum - write it once and only once. Then you get nearly exactly what you prefer:

for field in self.fields {
if field.value.isMissing() {
missingFields.append(field.name)
}
}

It would look something like this (from the Swift Interpreter):

  1> class Foo {}
>
2> enum Value {
3. case One(Foo!)
4. case Two(Foo!)
5.
6. func isMissing () -> Bool {
7. switch self {
8. case let .One(foo): return foo == nil
9. case let .Two(foo): return foo == nil
10. }
11. }
12. }
13> let aVal = Value.One(nil)
aVal: Value = One {
One = nil
}
14> aVal.isMissing()
$R0: Bool = true

Unwrapping associated value for all cases in switch

Try this in Playground.

enum RowType {
case single(_ content: [Any])
case double(_ content: [Any])
case triple(_ content: [Any])
case noVal

var associatedValue: Any? {
get {
let mirror = Mirror(reflecting: self)
if let associated = mirror.children.first {
return associated.value
}
print("WARNING: Enum option of \(self) does not have an associated value")
return nil
}
}
}

let row : RowType = .double([1,2,3])
let rowNoVal : RowType = .noVal
row.associatedValue
rowNoVal.associatedValue

Accessing a non raw type enumerations case values?

You need to use a switch here:

switch position {
case .top(let f):
// use f
case .middle(let f):
// use f
case .bottom(let f):
// use f
}

If you want it as an expression, you can do something like:

// you can assign the below to a variable or whatever
// let value =
{ () -> CGFloat in
switch position {
case .top(let f):
return f
case .middle(let f):
return f
case .bottom(let f):
return f
}
}()

However, I think the best solution is to redesign your types. It seems like there will always be a CGFloat associated with every case of your enum. Why not use a struct composing a simple enum and a CGFloat?

enum RelativeCardPosition {
case top
case middle
case bottom
}

struct CardPosition {
let relativeCardPosition: RelativeCardPosition
let offset: CGFloat

static func top(_ offset: CGFloat) -> CardPosition {
CardPosition(relativeCardPosition: .top, offset: offset)
}

static func middle(_ offset: CGFloat) -> CardPosition {
CardPosition(relativeCardPosition: .middle, offset: offset)
}

static func bottom(_ offset: CGFloat) -> CardPosition {
CardPosition(relativeCardPosition: .bottom, offset: offset)
}
}

Then you can easily access the number via position.offset.



Related Topics



Leave a reply



Submit