Accessing an Enumeration association value in Swift
The value is associated to an instance of the enumeration. Therefore, to access it without a switch, you need to make a getter and make it available explicitly. Something like below:
enum Number {
case int(Int)
case float(Float)
func get() -> NSNumber {
switch self {
case .int(let num):
return num
case .float(let num):
return num
}
}
}
var vInteger = Number.int(10)
var vFloat = Number.float(10.5)
println(vInteger.get())
println(vFloat.get())
Maybe in the future something like that may be automatically created or a shorter convenience could be added to the language.
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
Get enum parameter value
Inside ButtonType
enum, declare property like this:
enum ButtonType {
...
var value: String {
switch self {
case .number(let number): return number
case .clear(let clearValue): return clearValue
case .backspace(let backSpaceValue): return backSpaceValue
}
}
}
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
.
How to access second-level nested enum passed as parameter in Swift
You would need a giant switch statement to extract the cut styles,
for ingredient in salad {
let cutStyle: CutStyle?
switch ingredient {
case .lettuce(let cut):
cutStyle = cut
case .tomatoes(let cut):
cutStyle = cut
case .onions(let cut):
cutStyle = cut
case .cucumbers(let cut):
cutStyle = cut
case .dressing:
cutStyle = nil
}
print(cutStyle)
}
I think you could have modelled your salad better. Here are two alternative designs that allows you to access the cut style more easily.
One way is to make a SaladIngredient
struct that composes a cut style and an ingredient:
struct SaladIngredient {
enum Ingredient {
case lettuce
case tomatoes
case onions
case cucumbers
case dressing
}
enum CutStyle {
case diced
case chopped
case minced
case grated
}
let ingredient: Ingredient
let cutStyle: CutStyle?
}
func shareSalad(my salad: [SaladIngredient]) {
print("My salad contains:")
for ingredient in salad {
if let cutStyle = ingredient.cutStyle {
print(cutStyle)
}
}
}
The disadvantage of this is that it's harder to enforce the rule that dressings don't have a cut style.
Alternatively, collapse all those enum cases with a cut style into one case:
enum SaladIngredient {
enum Ingredient {
case lettuce
case tomatoes
case onions
case cucumbers
}
enum CutStyle {
case diced
case chopped
case minced
case grated
}
case cuttable(Ingredient, cutStyle: CutStyle)
case dressing
}
func shareSalad(my salad: [SaladIngredient]) {
print("My salad contains:")
for ingredient in salad {
if case .cuttable(_, cutStyle: let cutStyle) = ingredient {
print(cutStyle)
}
}
}
The disadvantage of this is that you are making .dressing
a totally different "type" of thing from lettuce, tomatoes and others.
How to compare enum with associated values by ignoring its associated value in Swift?
Edit: As Etan points out, you can omit the (_)
wildcard match to use this more cleanly.
Unfortunately, I don't believe that there's an easier way than your switch
approach in Swift 1.2.
In Swift 2, however, you can use the new if-case
pattern match:
let number = CardRank.Number(5)
if case .Number(_) = number {
// Is a number
} else {
// Something else
}
If you're looking to avoid verbosity, you might consider adding an isNumber
computed property to your enum that implements your switch statement.
How to make a Swift enum with associated values equatable
SE-0185 Synthesizing Equatable and Hashable conformance has been implemented in Swift 4.1, so that it suffices do declare conformance to the protocol (if all members are Equatable
):
enum ViewModel: Equatable {
case heading(String)
case options(id: String, title: String, enabled: Bool)
}
For earlier Swift versions, a convenient way is to use that tuples can be compared with ==
.
You many also want to enclose the compatibility code in a Swift version check, so that the automatic synthesis is used once the project is updated to Swift 4.1:
enum ViewModel: Equatable {
case heading(String)
case options(id: String, title: String, enabled: Bool)
#if swift(>=4.1)
#else
static func ==(lhs: ViewModel, rhs: ViewModel) -> Bool {
switch (lhs, rhs) {
case (let .heading(lhsString), let .heading(rhsString)):
return lhsString == rhsString
case (let .options(lhsId, lhsTitle, lhsEnabled), let .options(rhsId, rhsTitle, rhsEnabled)):
return (lhsId, lhsTitle, lhsEnabled) == (rhsId, rhsTitle, rhsEnabled)
default:
return false
}
}
#endif
}
Related Topics
How to Use String.Substringwithrange? (Or, How Do Ranges Work in Swift)
Swift Protocol With "Where Self" Clause
Opt Out of Uiscenedelegate/Swiftui on Ios
Check If 'Any' Value Is Object
Failing Cast in Swift from Any? to Protocol
How to Declare a Variable That Has a Type and Implements a Protocol
Swift Compiler Segmentation Fault When Building
Swift @Escaping and Completion Handler
Segue from Modal View to Tab Bar View Controller and Not Lose Tab Bar
How to Dispatch_Sync, Dispatch_Async, Dispatch_After, etc in Swift 3, Swift 4, and Beyond
Swift - Resolving a Math Operation in a String
Photopicker Discovery Error: Error Domain=Pluginkit Code=13
Unexpected Non-Void Return Value in Void Function (Swift 2.0)
Binary Operator * Cannot Be Applied to Operands of Type Int and Double
Removeobjectsatindexes For Swift Arrays