I'm trying to create an extension for my FieldIdentifiable protocol only where the enum that implements it has a RawValue of Int. The only problem is that the return FieldIdItem(rawValue: newValue)
line keeps showing this error:
'Self.FieldIdItem' cannot be constructed because it has no accessible initializers
Is this a Swift bug or am I missing something?
enum SignUpField: Int, FieldIdentifiable {
case Email = 0, Password, Username
typealias FieldIdItem = SignUpField
}
protocol FieldIdentifiable {
typealias FieldIdItem
func next() -> FieldIdItem?
func previous() -> FieldIdItem?
}
extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int {
func next() -> FieldIdItem? {
let newValue: Int = self.rawValue+1
return FieldIdItem(rawValue: newValue)
}
func previous() -> FieldIdItem? {
return FieldIdItem(rawValue: self.rawValue-1)
}
}
In
extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int { ... }
the associated type FieldIdItem
of Self
is not (necessarily)
RawRepresentable
, and that's why
FieldIdItem(rawValue: newValue)
does not compile. You could fix that by adding additional constraints:
extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int,
Self.FieldIdItem : RawRepresentable, Self.FieldIdItem.RawValue == Int { ... }
However, if the next()
and previous()
methods actually should
return instances of the same type then you don't need the
associated type at all, and can use Self
as return type in the protocol:
enum SignUpField: Int, FieldIdentifiable {
case Email = 0, Password, Username
}
protocol FieldIdentifiable {
func next() -> Self?
func previous() -> Self?
}
extension FieldIdentifiable where Self: RawRepresentable, Self.RawValue == Int {
func next() -> Self? {
return Self(rawValue: self.rawValue + 1)
}
func previous() -> Self? {
return Self(rawValue: self.rawValue - 1)
}
}
Note also that the constraint
Self.RawValue == Int
can be relaxed slightly to
Self.RawValue : IntegerType
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With