値型と参照型

値型と参照型

執筆済 ソフトウェア開発Swift

Swift の設計で最も影響が大きい区別。

値型 (value type) 参照型 (reference type)
該当 structenum、タプル classactor、クロージャ
代入 コピーされる 同じ実体を指す
同一性 無い(== のみ) === で比較できる
既定の格納 スタック(インライン) ヒープ
寿命管理 スコープで決まる ARC
swift
struct P { var x = 0 }
var a = P(); var b = a
b.x = 10
// a.x は 0 のまま

class C { var x = 0 }
let c = C(); let d = c
d.x = 10
// c.x も 10

なぜ値型を既定にするのか#

共有された可変状態が、バグの主要な源だから。

参照型では

  • どこから変更されるか分からない
  • [競合状態](/コンピュータ/並行・並列処理/Race Condition)が起きる
  • 変更が意図しない場所に波及する

値型はコピーされるので、 渡した先で変更されても自分は影響を受けない。 局所的に考えられる。

コピーのコスト#

大きな構造体を毎回コピーすると遅そうだが、 標準ライブラリのコレクション(Array、Dictionary、String)は コピーオンライトを実装している。

代入時       … 参照を共有するだけ(O(1))
書き込み時   … このとき初めて実体を複製する

参照カウントが 1 なら複製すら不要。 fork の CoW と同じ発想。

使い分け#

値型を選ぶ 参照型を選ぶ
データを表す 同一性が意味を持つ
不変・独立 状態を共有したい
比較が値の比較 継承が必要
並行処理で渡す Objective-C 連携

迷ったら struct というのが Swift の指針。

参考文献#

ノート一覧を閉じる