Swift:将协议变量实现为惰性变量?

时间:2018-01-02 14:01:02

标签: swift lazy-evaluation

似乎无法使用惰性变量实现协议所需的变量。例如:

protocol Foo {
  var foo: String { get }
}

struct Bar: Foo {
  lazy var foo: String = "Hello World"
}

编译器抱怨Type 'Bar' does not conform to protocol 'Foo'

也无法在协议声明中添加lazy关键字,因为这样会导致'lazy' isn't allowed on a protocol requirement错误。

这根本不可能吗?

1 个答案:

答案 0 :(得分:22)

引用the Language Guide - Properties - Lazy Stored Properties [强调我的]:

  

惰性存储属性是初始值不是的属性   计算直到第一次使用

即,首次使用时,该值为 mutated 。由于foo协议已将Foo蓝图标记为get,隐含nonmutating get,因此值类型Bar无法履行此承诺lazy } foo,一个带有mutating getter的属性。

Bar更改为引用类型将允许它实现Foo蓝图(因为改变引用类型的属性并不会改变类型实例本身):

protocol Foo {
    var foo: String { get }
}

class Bar: Foo {
    lazy var foo: String = "Hello World"
}

替代方案,在foo Foo属性的蓝图中指明它具有mutating吸气剂。

protocol Foo {
    var foo: String { mutating get }
}

struct Bar: Foo {
    lazy var foo: String = "Hello World"
}

有关getter和setter的mutating / nonmutating说明符的其他详细信息,请参阅以下Q& A: