The default value for Enum in Swift

I have an enum :

 public enum PersonType:String { case Cool = "cool" case Nice = "rude" case SoLazy = "so-lazy" public var description: String { switch self { case .Cool: return "Cool person" case .Nice: return "Nice person" case .SoLazy: return "its so lazy person" } } public var typeImage: String { switch self { case .Cool: return "cool.png" case .Nice: return "img_nice.png" case .Solazy: return "lazy.png" } } } 

Problem: I do not know all the keys of the type of person, so I need to handle the case with the default type of personalization and give him a description of whether it will be key, like a "lazy" and default image.

let's say I get this result from a web service:

 [ { name: "john", key: "cool" }, { name: "paul", key: "funny" } ] 

I need to have a default case for handling the key "funny"

this is how I initialize my enumeration when parsing and creating a person object:

 if let personType = PersonType(rawValue:personTypeKey ?? "") { self.personType = personType } 

I want an else or better approach to handle random keys in my enumeration and give them a key as a description and default image.

+11
source share
9 answers

Another approach that works in Swift 3 (maybe 2, I don't know):

 enum PersonType: String { case cool = "cool" case nice = "nice" case soLazy = "so-lazy" case other } let person = PersonType(rawValue: "funny") ?? .other 

The private variable is of type PersonType.other in this case.

The disadvantage of this is that you do not know the string value of another case.

+16
source

Drop the raw type and use enum with the associated value:

 public enum PersonType { case Cool case Nice case SoLazy case Unknown(String) static func parse(s:String) -> PersonType { switch s { case "Cool" : return .Cool case "Nice" : return .Nice case "SoLazy" : return .SoLazy default: return Unknown(s) } } } 

The disadvantage of this method is that you have to provide some logic to analyze known enum values. However, the growth potential is that you can put something else in another Unknown case, while preserving the actual โ€œunknownโ€ value for later use.

+13
source

This is pretty close, but I would like to be able to save a value that might be related to it, sort of like C.

 enum Errors: Int { case transactionNotFound = 500 case timeout = -1001 case invalidState = 409 case notFound = 404 case unknown init(value: Int) { if let error = Errors(rawValue: value) { self = error } else { self = .unknown } } } Errors(value: 40) // .unknown Errors(value: 409) // .invalidState Errors(value: 500) // .transactionNotFound 

I had to create a custom initializer, otherwise it will be recursive. And you can still create using the rawValue initializer randomly.

This, however, feels more Swifty, I removed the type specifier : Int , which allows the use of related values, now the exceptional case that we are not doing anything special is handled in other :

 enum Errors2 { case transactionNotFound case timeout case invalidState case notFound case other(Int) init(rawValue: Int) { switch rawValue { case 500: self = .transactionNotFound case -1001: self = .timeout case 409: self = .invalidState case 404: self = .notFound default: self = .other(rawValue) } } } Errors2(rawValue: 40) // .other(40) Errors2(rawValue: 409) // .invalidState Errors2(rawValue: 500) // .transactionNotFound Errors2(rawValue: -1001) // .timeout 

With this, I can get the actual value for the โ€œotherโ€ error, and I can use rawValue to act just like an int based enum. There is one case statement for matching names, but from now on you can use names and should never refer to numbers.

+7
source

So:

 init() { self = .Cool } 
+3
source

In Swift 5.1, you can now set the default values. Your code will look like this:

 enum PersonType { case cool(String = "cool") case nice(String = "rude") case soLazy(String = "so-lazy") } 
+2
source

Try this approach.

 public enum PersonType:String { case Cool = "cool" case Nice = "rude" case SoLazy = "so-lazy" static let allKeys = [Cool.rawValue, Nice.rawValue, SoLazy.rawValue] } extension PersonType { func description(personTypeKey : String) -> String { if PersonType.allKeys.contains(personTypeKey) { switch self { case .Cool: return "Cool person" case .Nice: return "Nice person" case .SoLazy: return "its so lazy person" } } else { return "YourTextHere" } } func typeImage(personTypeKey : String) -> String { if PersonType.allKeys.contains(personTypeKey) { switch self { case .Cool: return "cool.png" case .Nice: return "img_nice.png" case .SoLazy: return "lazy.png" } } else { return "YourImageHere" } } } 
+1
source

For you:

The default value for Enum is : I just add the default property, calculated, Or enable the init setting.

 public enum PersonType:String { case Cool = "cool" case Nice = "rude" case SoLazy = "so-lazy" /// add a `default` computer property public static var `default`: PersonType { return .SoLazy } /// add an customize init function public init(person: String? = nil) { if let person = person { switch person { case "cool": self = .Cool case "rude": self = .Nice case "so-lazy": self = .SoLazy default: self = .SoLazy } } else { self = .SoLazy } } public var description: String { switch self { case .Cool: return "Cool person" case .Nice: return "Nice person" case .SoLazy: return "its so lazy person" } } public var typeImage: String { switch self { case .Cool: return "cool.png" case .Nice: return "img_nice.png" case .SoLazy: return "lazy.png" } } } 

For use:

 if let personType = PersonType(rawValue:personTypeKey ?? "") { self.personType = personType } else { self.personType = PersonType.default } 

or

 if let personType = PersonType(rawValue:personTypeKey ?? "") { self.personType = personType } else { self.personType = PersonType() } 

The default value for Enum with the associated value:

 public enum Gender { case man case woman } public enum PersonType { case cool(Gender) case nice(Gender) case soLazy(Gender) public static var `default`: PersonType { return PersonType.make.soLazy() } public enum Builder { public static func cool() -> PersonType { return PersonType.cool(.woman) } public static func nice() -> PersonType { return PersonType.nice(.woman) } public static func soLazy() -> PersonType { return PersonType.soLazy(.woman) } } public static var make: PersonType.Builder.Type { return PersonType.Builder.self } public var description: String { switch self { case .cool(let gender): switch gender { case .man: return "Cool boy" case .woman: return "Cool girl" } case .nice(let gender): switch gender { case .man: return "Nice boy" case .woman: return "Nice girl" } case .soLazy(let gender): switch gender { case .man: return "its so lazy boy" case .woman: return "its so lazy girl" } } } public var typeImage: String { switch self { case .cool(_): return "cool.png" case .nice(_): return "img_nice.png" case .soLazy(_): return "lazy.png" } } } 

For use:

 let onePersonType = PersonType.default let anotherPersonType = PersonType.make.soLazy() 

The second solution was found on Ilya Puchka's Blog . And also he is mentioned in a quick sentence .

+1
source

Interestingly, the dictionary does not fit better than the listing here:

 let dict = [ "Cool": "cool", "Nice": "rude", "SoLazy": "so-lazy" ] let personType = "unknown" let personDescription = dict[personType] ?? "Unknown" 

Smaller customization, faster processing, more natural default case handling, simpler extension.

0
source

To answer your question:

 public enum PersonType:String { case Cool = "cool" case Nice = "rude" case SoLazy = "so-lazy" static var 'default': PersonType { return .SoLazy } public init(rawValue: RawValue) { switch rawValue { case PersonType.Cool.rawValue: self = .Cool case PersonType.Nice.rawValue: self = .Nice case PersonType.SoLazy.rawValue: self = .SoLazy default: self = .default } } public var description: String { switch self { case .Cool: return "Cool person" case .Nice: return "Nice person" case .SoLazy: return "its so lazy person" } } public var typeImage: String { switch self { case .Cool: return "cool.png" case .Nice: return "img_nice.png" case .SoLazy: return "lazy.png" } } } 

Now, since you do not have a failed initializer with a default value, replace yours:

 if let personType = PersonType(rawValue:personTypeKey ?? "") { self.personType = personType } 

WITH:

 personType = PersonType(rawValue: personTypeKey) 
0
source

All Articles