I want a enumeration of countries, like:
enum Country: Int {
case Afghanistan
case Albania
case Algeria
case Andorra
//...
}
There are two main reasons why I choose Int
as its rawValue type:
I want to determine the total count of this enumeration, using
Int
as rawValue type simplifies this:enum Country: Int { case Afghanistan // other cases static let count: Int = { var max: Int = 0 while let _ = Country(rawValue: max) { max = max + 1 } return max }() }
I also need a complicated data structure that represents a country, and there is an array of that data structure. I can easily subscript-access certain country from this array using Int-valued enumeration.
struct CountryData { var population: Int var GDP: Float } var countries: [CountryData] print(countries[Country.Afghanistan.rawValue].population)
Now, I somehow need to convert a certain Country
case to String
(aka. something like
let a = Country.Afghanistan.description // is "Afghanistan"
Since there are lots of cases, manually writing a conversion-table-like function seems unacceptable.
So, how can I get these features at once ?:
- Use enumeration so potential typo-caused bugs can be found during compile time. (Country.Afganistan won't compile, there should be an 'h' after 'g', but some approach like countries["Afganistan"] will compile and may cause runtime errors)
- Be able to determine the total country count programmatically (likely to be able to determine at the compile time, but I don't want to use a literal value and keep in mind to change it properly every time I add or remove a country)
- Be able to easily subscript-like access a metadata array.
- Be able to get a string of a
case
.
Using enum Country: Int
satisfies 1, 2, 3 but not 4
Using enum Country: String
satisfies 1, 3, 4 but not 2 (use Dictionary instead of Array)