There are examples on Swift book demonstrating associated values and raw values separately, is there a way to define enums with the two features together?
I have tried to combine them, but got errors:
enum Barcode :String { case UPCA(Int, Int, Int) = "Order 1" // Enum with raw type cannot have cases with arguments case QRCode(String) = "Order 2" // Enum with raw type cannot have cases with arguments }
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.
The raw value for a particular enumeration case is always the same. 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.
What is the difference between an Associated value and a Raw value in Swift ? Associated value : Associated types can be of any type, not just strings or numbers. Raw value : Raw values are for when every case in the enumeration is represented by a compile-time-set value.
An enum is a special type of variable that is specifically used with switch and conditionals. Swift enumeration cases don't have unique default integer values (like an array), unlike languages such as TypeScript and Objective C where the first element has a value of 0 , the second a value of 1 , and so on.
Yes this is possible. An enum may contain both associated values and raw values. (Swift 5 & 4)
The issue with your code is that you are using the shorthand notation for RawRepresentable
and defining associated types.
Let's look at how to define these separately:
1) RawRepresentable
(shorthand notation):
enum Barcode: String { case UPCA = "order 1" case QRCode = "order 2" }
2) Associated types:
enum Barcode { case UPCA(Int, Int, Int) case QRCode(String) }
Each of these is great, but what if you need both as your code snippet shows.
Define the enum with associated values and then implement conformance to RawRepresentable
separately in an extension (i.e. not using shorthand notation).
Example:
enum Barcode { case UPCA(Int, Int, Int) case QRCode(String) } extension Barcode: RawRepresentable { public typealias RawValue = String /// Failable Initalizer public init?(rawValue: RawValue) { switch rawValue { case "Order 1": self = .UPCA(1,1,1) case "Order 2": self = .QRCode("foo") default: return nil } } /// Backing raw value public var rawValue: RawValue { switch self { case .UPCA: return "Order 1" case .QRCode: return "Order 2" } } }
Minor Detail
In this solution, defaults for the associated values, e.g. .UPCA(1,1,1)
must be supplied when constructing the enum from the rawValue argument. You can get fancy and use the associated types as part of the backing raw value — which is more powerful, but adds some complexity.
References
For more info on the topic see Ole Begemann's excellent write up.
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