robnik
1
I guess you just can't use protocol defaults in this situation. I'm trying to make it easy for enums that are RawRepresentable to conform to ColumnMappable.
protocol ColumnMappable {
static var typeStr: String { get }
static var nullable: Bool { get }
}
extension ColumnMappable {
// A default
static var nullable: Bool { false }
}
extension String: ColumnMappable {
static let typeStr: String = "text"
}
extension RawRepresentable where RawValue: ColumnMappable {
static var typeStr: String { RawValue.typeStr }
// This is the `nullable` I want, but compiler doesn't know that.
static var nullable: Bool { RawValue.nullable }
}
// Error here
enum MyEnum: String, ColumnMappable { case a, b, c }
The error points to the 2 definitions of nullable and says:
Multiple matching properties named 'nullable' with type 'Bool'
Nevin
2
Make the last extension include a Self: ColumnMappable constraint.
1 Like
robnik
3
Man, you guys are good. :) I'm happy it works, but I don't see why it does. Do you?
Nevin
4
In your original code, there are two independent implementations: one from ColumnMappable and one from RawRepresentable.
By adding the constraint, the second implementation is no longer independent: both fall under ColumnMappable, and the more-specific one is chosen.
• • •
From a purely human-readability standpoint, one might prefer to write:
extension ColumnMappable where Self: RawRepresentable, RawValue: ColumnMappable
So that all the implementations are visually-obviously in extensions of ColumnMappable.
2 Likes