web-dev-qa-db-ja.com

Swift:プロトコル変数を遅延varとして実装しますか?

遅延変数を使用して、プロトコルで必要な変数を実装することはできないようです。例えば:

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エラーが発生します。

これはまったく不可能ですか?

22
Kevin Renskers

引用 言語ガイド-プロパティ-遅延保存プロパティ [emphasismine]:

遅延保存プロパティは、最初に使用されるまで初期値が計算されないプロパティです

つまり、値は最初の使用時にmutatedになります。 fooFooプロトコルでgetとして設計されているため、暗黙的にnonmutating get、値タイプBarは、lazyプロパティfoomutatingゲッターを持つプロパティでは、この約束を満たしません。

Barを参照型に変更すると、Fooブループリントを満たすことができます(参照型のプロパティを変更しても型インスタンス自体は変更されないため)。

protocol Foo {
    var foo: String { get }
}

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

または、fooFooプロパティのブループリントで、mutatingゲッターがあることを指定します。

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

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

ゲッターおよびセッターのmutating/nonmutating指定子の詳細については、次のQ&Aを参照してください。

26
dfri