Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can associated values and raw values coexist in Swift enumeration?

Tags:

enums

swift

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 } 
like image 496
vladof81 Avatar asked Jun 11 '14 20:06

vladof81


People also ask

What is associated values in enum Swift?

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.

What is raw value and associated value Swift?

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's the difference between raw values and associated values?

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.

Can enums have variables Swift?

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.


1 Answers

Yes this is possible. An enum may contain both associated values and raw values. (Swift 5 & 4)

Shorthand notation

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.

Solution

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.

like image 77
cjmconie Avatar answered Oct 03 '22 20:10

cjmconie