0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Swift: なぜ遅延保存プロパティはvarでのみ宣言可能なのか?

Posted at

Swiftを学習する中で、遅延保存プロパティ(lazy stored property)はvarでのみ宣言できる一方で、タイプ保存プロパティ(type stored property)はletとvarの両方で宣言可能であることに気付きました。この違いについて、具体的なコード例を交えて考察してみます。


1. コード例

以下のAnimationクラスを見てみましょう。

class Animation {
    static let genere = "animation" // タイプ保存プロパティ
    let name: String
    var rate: Double
    lazy var series: Int = 0 // 遅延保存プロパティ
    
    init(name: String, rate: Double) {
        self.name = name
        self.rate = rate
    }
}

このクラスには以下のプロパティが含まれています。

  • genere: タイプ保存プロパティ(static let)
  • series: 遅延保存プロパティ(lazy var)

次の3つの手順でプロパティの挙動を確認してみましょう。

  1. aniというインスタンスを生成 → 確認
  2. series(遅延保存プロパティ)にアクセス → 確認
  3. genere(タイプ保存プロパティ)にアクセス → 確認

[1]インスタンスの生成

let ani = Animation(name: "ani", rate: 3.0) // インスタンス生成
ani

스크린샷 2025-03-01 오전 3.00.51.png

インスタンスを生成すると、遅延保存プロパティseriesはまだ初期化されていません。デバッグ情報を確認すると、$__lazy_storage_$_series という内部変数が nil になっていることが分かります。

[2] 遅延保存プロパティにアクセス

ani.series // 遅延保存プロパティにアクセス
ani

스크린샷 2025-03-01 오전 3.01.45.png

このタイミングで初めて series に値が設定されます。アクセスする前までは nil だったのが、値 0 に変更されていることが確認できます。

[3] タイプ保存プロパティにアクセス

Animation.genere // タイプ保存プロパティにアクセス
ani

스크린샷 2025-03-01 오전 3.02.42.png

タイプ保存プロパティgenereにアクセスしても、インスタンスaniの状態には何の変化もありません。これは、タイプ保存プロパティがインスタンスに属するものではなく、クラス(型)そのものに属するプロパティだからです。


2. 結論

遅延保存プロパティ(lazy stored property)

  • アクセスするまで初期化されない
  • 初期化される前は、nilの状態(内部的にはOptional型として扱われる)
  • letはインスタンス生成時に値を必ずセットする必要があるため、lazyとは相性が悪い
  • そのため、lazyvarとしか併用できない

つまり、遅延保存プロパティは「値の設定の遅延」が目的であり、varのみ許容されるということになります。

タイプ保存プロパティ(type stored property)

  • 最初にアクセスされるまでメモリのデータ領域にロードされない(=lazyな動作)
  • letvarの両方が可能(値の変更可否に依存する)
  • メモリのデータ領域を効率よく使用するために、アクセスされたときに初めてロードされる

つまり、タイプ保存プロパティは「メモリ効率の向上」が目的であり、lazyな動作をするが、値の変更可否(let/var)とは独立しているということになります。


3. まとめ

プロパティの種類 let使用 var使用 初期化のタイミング
インスタンス保存プロパティ インスタンス生成時
遅延保存プロパティ(lazy) 最初にアクセスされたとき
タイプ保存プロパティ(static) 最初にアクセスされたとき
  • 遅延保存プロパティは、インスタンスのプロパティとして初期化の遅延が目的 → letと相性が悪いため varのみ
  • タイプ保存プロパティは、メモリの効率化が目的 → let/varどちらも可能

このように、遅延保存プロパティのlazyと、タイプ保存プロパティのlazyな挙動は、それぞれ目的が異なるため、letの使用可否にも違いが生じるということが分かりました。


⚠️ 注意:
この文書の内容には誤りが含まれている可能性があります。
もし間違いや改善点がありましたら、ご指摘いただけると幸いです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?