Given the following interface:
protocol Animal {
var head : AnimalHead { get }
}
protocol AnimalHead {}
A Horse module might implement it as such:
struct Horse : Animal {
// let head = HorseHead() // [1]
let _head = HorseHead()
var head: AnimalHead { _head } // [2]
}
struct HorseHead : AnimalHead {}
Unfortunately, it appears the language does not permit [1]
and forces me to use a workaround [2]
to implement the head
property requirement.
Can anyone explain why this limitation exists? I would understand that it is impossible for the compiler to accept [1]
if the property was {get set}
, seeing as it's not possible to honour the guarantee of the protocol in that case, but seeing as the property is read-only, I do not see why this restriction exists and the example demonstrates that it is in fact trivial to implement correctly.
What's going on here? Should the compiler consider allowing [1]
in the case of read-only properties?
The same is of course true for function return values. In the following code, Horse
is theoretically fully compliant with the contract requirements of Animal
, but the compiler refuses to permit it:
protocol Animal {
func copy() -> Animal
}
struct Horse : Animal {
func copy() -> Horse { // Compiler error
Horse()
}
}
On the other hand, the following is perfectly permissible:
struct Horse : Animal {
func copyHorse() -> Horse {
Horse()
}
func copy() -> Animal {
copyHorse()
}
}
There does not appear to be any legitimate reason for why the latter should be allowed but the former illegal.
That is – per my understanding, a protocol definition such as:
func copy() -> Animal
is a contract requiring that any implementation of copy
yields an instance that supports at a bare minimum the contract requirements of the Animal
type. It appears that the way these things have currently been implemented in the compiler is to require that the implementation of copy
may only support the contract requirements of Animal
and nothing more - and I can't fathom a reason as to why this should be enforced.