The simple generic NonEmpty
struct is really a powerful type and I wish for its inclusion in the stdlib in the future, but that's not the topic of this thread. Collection
has a requirement var first: Self.Element? { get }
which must be satisfied by the conforming type. This requirement has however a default implementation, which allows NonEmpty
to be implemented in a convenient way by providing a non-optional first
property.
At the first glance I thought there is a rule that allows us to satisfy protocol requirements with non-optional types, but this resulted in an error. Only after further investigation I noticed that a default implementation must exist in order to 'kind of override' the requirement with a non-optional version.
protocol P {
var e: Int? { get }
}
extension P {
var e: Int? {
return 42
}
}
extension P {
func foo() {
print(e as Any)
}
}
struct T : P {}
extension T {
var e: Int {
return 0
}
}
let t = T()
// prints "0 Optional(42) Optional(42)"
print(
t.e,
(t as P).e as Any,
t.e as Optional as Any
)
t.foo() // prints "Optional(42)"
- Why does the compiler allow this shadowing?
- This might have unexpected behavior when static dispatch is applied.
- Why is
t.e
not ambiguous for the compiler? - Would it make any sense to allow protocol requirement satisfaction with non-optional types, like with failable init's? (Probably with some implicit optional promotion.)
protocol Q {
init?()
}
struct S : Q {
init() {} // Okay
}
// Return type must be an optional
func create<T>(_: T.Type) -> T? where T : Q {
return T.self.init()
}