It seems that it's not possible to implement a variable that's required by a protocol, with a lazy variable. For example:
protocol Foo {
var foo: String { get }
}
struct Bar: Foo {
lazy var foo: String = "Hello World"
}
Compiler complains that Type 'Bar' does not conform to protocol 'Foo'
.
It's also not possible to add the lazy
keyword in the protocol declaration, since then you get 'lazy' isn't allowed on a protocol requirement
error.
So is this not at all possible?
Citing the Language Guide - Properties - Lazy Stored Properties [emphasis mine]:
A lazy stored property is a property whose initial value is not calculated until the first time it is used.
I.e., the value is mutated upon first usage. Since foo
has been blueprinted in the Foo
protocol as get
, implicitly nonmutating get
, the value type Bar
does not fulfil this promise with its lazy
property foo
, a property with a mutating
getter.
Changing Bar
to a reference type will allow it to fulfil the Foo
blueprint (as mutating a property of a reference type doesn't mutate the type instance itself):
protocol Foo {
var foo: String { get }
}
class Bar: Foo {
lazy var foo: String = "Hello World"
}
Alternative, specify in the blueprint of the foo
property of Foo
that it has a mutating
getter.
protocol Foo {
var foo: String { mutating get }
}
struct Bar: Foo {
lazy var foo: String = "Hello World"
}
See the following Q&A for some additional details of the mutating
/nonmutating
specifiers for getters and setters: