Reputation: 1479
In the Swift book, the example for enums works fine
enum CompassPoint: String {
case north, south, east, west
}
var northCom = CompassPoint.north
print (northCom)
However I want to use a failable initializer so made an example of this
enum WeekDay: String {
case monday, tuesday, wednesday, thursday, friday
init?(rawValue: Int){
switch rawValue {
case 0 : self = .monday
case 1 : self = .tuesday
case 2 : self = .wednesday
case 3 : self = .thursday
case 4 : self = .friday
default : return nil
}
}
}
And get an error that Weekday does not conform to RawRepresentable - although I feel that conformance should be synthesized by the compiler so do not understand why this does not compile.
What I've done Created a similar working example (to see what the issue is), and still I want to conform to RawRepresentable using an enum with a failable initializer. I cannot find an example of this in the Swift book, in Stack Overflow questions or on the wider internet.
What I've provided Given a full example above, with the error as well as a working example of the behaviour I'm expecting.
What is not helpful Referencing the Swift book through a link or a comment is not helpful, as I've taken an example from there. I want to build on that example with a failable initializer. It is also not helpful to NOT use a enum, or a failable initializer. The question is about using a failable initalizer with a enum, and conforming to RawRepresentable. This is not homework, but those are the constraints of the question for my own learning and I'm interested in the outcome.
The question How can I use a failable initializer, with an enum as in the non-working example?
Upvotes: 13
Views: 24906
Reputation: 5135
As of Swift 5 there is no error of having a second init?(rawValue: Int)
in addition to synthesized init?(rawValue: String)
. But if you want to override that RawRepresantable
implementation and have rawValue
be Int
, it is possible.
extension WeekDay : RawRepresentable {
typealias RawValue = Int
init?(rawValue: Int){
switch rawValue {
case 0 : self = .monday
case 1 : self = .tuesday
case 2 : self = .wednesday
case 3 : self = .thursday
case 4 : self = .friday
default : return nil
}
}
var rawValue: Int {
switch self {
case .monday : return 0
case .tuesday : return 1
case .wednesday : return 2
case .thursday : return 3
case .friday : return 4
}
}
}
print(WeekDay.init(rawValue: 2)) // Optional(WeekDay.wednesday)
print(WeekDay.RawValue.self) // Int
Upvotes: 1
Reputation: 2359
"although I feel that conformance should be synthesized by the compiler"
Yes, here your rawValue
is of type String, not Int. Simply create your enum like:
enum WeekDay: String {
case monday, tuesday, wednesday, thursday, friday
}
And then create a WeekDay
like this:
let monday: WeekDay? = WeekDay(rawValue: "monday")
let notADay: WeekDay? = WeekDay(rawValue: "foo")
Of course you can also add a custom init which takes an integer as argument:
enum WeekDay: String {
case monday, tuesday, wednesday, thursday, friday
init?(integer: Int){
switch integer {
case 0 : self = .monday
case 1 : self = .tuesday
case 2 : self = .wednesday
case 3 : self = .thursday
case 4 : self = .friday
default : return nil
}
}
}
And create your weekDay like:
let monday: WeekDay? = WeekDay(integer: 0)
let notADay: WeekDay? = WeekDay(integer: 30)
Upvotes: 4
Reputation: 540135
Apparently your definition of init?(rawValue: Int)
prevents the compiler from inferring the RawValue
type automatically. Adding a type alias helps:
enum WeekDay: String {
typealias RawValue = String
case monday, tuesday, wednesday, thursday, friday
init?(rawValue: Int){
switch rawValue {
case 0 : self = .monday
case 1 : self = .tuesday
case 2 : self = .wednesday
case 3 : self = .thursday
case 4 : self = .friday
default : return nil
}
}
}
Alternatively define your custom init function with a different parameter name:
enum WeekDay: String {
case monday, tuesday, wednesday, thursday, friday
init?(rawInt: Int){
switch rawInt {
case 0 : self = .monday
case 1 : self = .tuesday
case 2 : self = .wednesday
case 3 : self = .thursday
case 4 : self = .friday
default : return nil
}
}
}
Upvotes: 15