Enums In Swift

Introduction

 
Enum consists of zero or more cases, with each case having an optional tuple style list of associated values. A case contains many associated values, but is considered as a single tuple. Enum has similar syntax as class syntax. The syntax of enum is shown below,
  1. enum Text
  2. {    
  3.  case l1 
  4.  case c1    
  5.  case r1    
  6. }    
The result type to represent the success or failure of an operation adds a second associated value for the failure cases and enables it to capture detailed error information.
 
The full type annotation needs to be provided including the generic parameters. Enum is special data type and it enables a variable to be a set of predefined constants. It is used when the possible values are known.
  • Enums have methods and subscripts.
  • Methods can be declared mutating or non mutating.
  • Extension are used in enums and it conforms to the protocol.

Value types

 
Enums are value types and cannot have stored properties. Enum state is represented by its case associated value. Associated values are stored properties for the particular case. The enums are mutated by assigning a new value directly to the self. The initialization of enum is to assign it a case. It is possible to add additional initializers in type definition or extension. The initializer is added to our text alignment enum that sets a defaut text alignment for locale as shown below,
  1. extension Text {  
  2.     init(defaultFor locale: Locale) {  
  3.         guard  
  4.         let language = locale.languageCode  
  5.         else {  
  6.             self = .left  
  7.             return  
  8.         }  
  9.         switch Locate.characterDirection(forLanguage: language) {  
  10.             case.rightToLeft: self = .right  
  11.             case.leftToRight, .topToBottom, .bottomToTop, .unknown: self = .left  
  12.             @unknown  
  13.             default: self = .left  
  14.         }  
  15.     }  
  16. }  
  17. let english = Locate(identifier: "en_AU")  
  18. Text(defaultFor: english)  
  19. let arabic = Locale(identifier: "arEG")  
  20. Text(defaultFor: arabic)   

Pattern matching

 
Switch statement is to inspect an enum and and it has a convenient syntax for comparing a value against a particular case and extracting the associated values. Pattern matching is the most prominent use case and it is used to decompose a data structure by its shape. Pure matching is able to combine with value binding. The case begins with one or more patterns and the input value is matched to it. 
 
Wildcard pattern
 
It is used for ignoring part of an associated value while matching another. In switch statement case is equivalent to the default key word.
 
Tuple pattern
 
It matches tuples with a common separated list of zeros and it matches a tuple with three elements where the second element is 0 and binds with the first element.
 
Enum case pattern
 
It matches the specified enum case and the pattern includes the subpattern for the associated values. To ignore the associated value the underscore is used.
 
Value binding pattern
 
It binds the matched value to new content and the scope of the new variable is the case block as it appears.
 
The pattern .failure matches the failure case and binds with associated value to the local error:
  1. let result : Result < (Int, String), Error>=  
  2.   
  3. switch result  
  4. {  
  5.  case.success (42, _):  
  6.  print (" The number is found ")  
  7.  case.success (_):  
  8.  print (" Another number is found ")  
  9.  case.failure (let error):  
  10.  print("Error:\(error)")  
  11. }  
Type Casting Pattern
 
If the value runtime type is the same as the specified type, the pattern of some type matches. Some type perfoms the same check and additionally casts the matched value to the specified type.
  1. let input : Any =     
  2. switch input    
  3. {    
  4.  case let integer as int :     
  5.  case let string as String:    
  6.  default : fatalError (" Error occured")    
  7. }    
Designing with Enums
 
Enums have different design patterns since true sum types are uncommon and work with traditional object oriented approaches. The main use of enum is to make illegal states impossible and use enums for modelling state and recusrsive data structures.