4 ms·
Can someone give a quick overview of whats going on with this code? I'm feeling a bit lost on how enums are being declared and used in swift. enum ActionToke
by seanalltogether 12y ago
Can someone give a quick overview of whats going on with this code? I'm feeling a bit lost on how enums are being declared and used in swift.
enum ActionToken {
case NoAction(source: Int, value: Int)
case Move(source: Int, value: Int)
case SingleCombine(source: Int, value: Int)
case DoubleCombine(source: Int, second: Int, value: Int)
// Get the 'value', regardless of the specific type
func getValue() -> Int {
switch self {
case let .NoAction(_, v): return v
case let .Move(_, v): return v
case let .SingleCombine(_, v): return v
case let .DoubleCombine(_, _, v): return v
}
}
// Get the 'source', regardless of the specific type
func getSource() -> Int {
switch self {
case let .NoAction(s, _): return s
case let .Move(s, _): return s
case let .SingleCombine(s, _): return s
case let .DoubleCombine(s, _, _): return s
}
}
}
- TheCoreh 12y agoSwift's enums are like Rust's enums, so they're much more powerful than C's enums: In C an enum can assume one of multiple predefined values of type `int`. In Swift an enum can work like that too, but it can also assume values of types other than int. This is similar to the behavior of the unions in C, but more high level, with proper safety checks in place. In Swift enums can also have methods, so there are two methods to return fields from the values contained in the enum —regardless of the actual type being held at that time.
- Glide 12y agoAnd the functions there are examples of pattern matching in Swift. To the GP. That code example is a very good example of just how different Swift code be from Objective-C.
- seanalltogether 12y agocase let .DoubleCombine(s, _, _): return s Is the underscore a special character in this case to tell the compiler not to read in the value of those arguments? Or is it actually loading in "second" and then "value" into an argument named _?
- weego 12y agoAssuming it's the same as other pattern matching langs it is a wildcard that signals the intent that you don't care about what value those would be.
- Someone 12y agoThe computer science name for that is sum type, the (or maybe just the simplest) implementation a tagged union (maybe I'm making up that distinction; Wikipedia thinks they are synonyms (http://en.wikipedia.org/wiki/Sum_type) http://en.wikipedia.org/wiki/Sum_type)). You can do ~the same~ in C with a struct and an union: typedef sruct s { int type; union { int i; float f; double d; } value; } But there, it is up to you to make sure that you only read the int/float/double if the 'type' field indicates a int/float/double was stored. Higher-level languages enforce that you can only read the union as being of type T if you wrote it as type T.
- sampo 12y agoIt's the same as case classes and pattern matching in Scala [1]. Or case expression and pattern matching in Haskell [2]. Or in OCaml [3]. Or in Rust [4]. [1] http://docs.scala-lang.org/tutorials/tour/case-classes.html http://docs.scala-lang.org/tutorials/tour/case-classes.html [2] http://learnyouahaskell.com/syntax-in-functions#pattern-matching http://learnyouahaskell.com/syntax-in-functions#pattern-matc... "case expressions" at the end of the page. [3] http://ocaml.org/learn/tutorials/data_types_and_matching.html http://ocaml.org/learn/tutorials/data_types_and_matching.htm... [4] http://static.rust-lang.org/doc/master/tutorial.html#control-structures http://static.rust-lang.org/doc/master/tutorial.html#control...
- JoshTriplett 12y ago> case let .NoAction(_, v): return v That's amazingly awkward syntax for a brand-new language. "case let"? In many other languages with pattern matching and destructuring, the "let" occurs implicitly.
- thinkpad20 12y agoThe reason why they don't do that is that you can reference variable names: foo = 1 switch bar { // Equals the value of (existing) variable foo case foo: return 0 // Catch-all, binds `foo` to whatever is in `bar` case let foo: return foo + 1 } (My syntax might be off, I've never written Swift) To do this in Haskell, you'd have to write something like: foo = 1 case bar of foo' | foo' == foo -> 0 foo -> foo + 1 Because you're only able to pattern-match against literal objects (constructors or numeric/string literals). This might be different in some other ML-like languages, or there could be GHC extensions for this, of course.
- yeldarb 12y agoIn Swift this could also be written as > case .NoAction(_, let v): return v Putting it at the beginning makes it apply to all the variables in the parens (although in this case they are ignoring the first one by using the underscore). Using "let" makes it immutable; you can also use "var" there to make it a variable you can modify in the case body.