ミュータブルとイミュータブルの違い

目次

ミュータブルとイミュータブルの違いのまとめ

定義 特徴 用途
ミュータブル
mutable
変更可能
オブジェクトを生成した後でも、中身(値や状態)を書き換えられる。
メモリ効率が良く、高速に更新できる
どこで変更されたか追いにくく、バグの温床になりやすい
データを繰り返し更新する処理(配列の加算、キャッシュ更新など)
イミュータブル
immutable
変更不可
一度作られたオブジェクトは中身を変えられず、新しい値を作り直す必要がある。
安全(予期せぬ変更を防ぎバグを減らす)
更新のたびに新しいオブジェクトを作るためメモリ効率は悪い
データの一貫性を守る処理(文字列、ID、定数値など)

並行処理が絡む場面では イミュータブルが推奨されるケースが多いです。

ミュータブル(可変)

以下は、インスタンスの値が2のとき、1を追加するとインスタンスの値が3になる図です。

  • ミュータブルは、インスタンス(オブジェクト)の状態を変更できるインスタンス(オブジェクト)です。
  • 日時の計算等で使用するPHPのDateTimeのインスタンスは、日時の加算でインスタンスの状態が変わります。
    →ミュータブルです。
  • 想定していない更新が起こる可能性があるためイミュータブルより安全性は落ちます
  • ミュータブル(mutable)は、可変という意味です。

ミュータブルのサンプルです。コードはPHPです。

<?php
//ミュータブルの例
$date1 = new DateTime('2020-8-10 22:30:10');

// 3日後を求める
$date2 = $date1->modify("+3 day");
print $date2->format("Y/m/d"); // 2020/08/13

// 3日後を求める
$date3 = $date1->modify("+3 day");
print $date3->format("Y/m/d"); // 2020/08/16

3行目は、DateTimeのインスタンスを生成しています。
6行目は、$date1の3日後を求め、$date2に代入しています。
このときインスタンスの$date1も3日増えます。(状態が変わる)

10行目は、3行目の$date1の3日後を求めようとしますが、
6行目で$date1は3日増えた状態になっているので
結果として$date3は6日増えます。
→ミュータブルです。

イミュータブル(不変)

以下は、インスタンスの値が2のとき、1を追加すると元のインスタンスの値は2のままで、値3のインスタンスのコピーを返すことを説明した図です。

  • イミュータブルは、インスタンス(オブジェクト)の状態を変更できないインスタンス(オブジェクト)です。
  • 日時の計算等で使用するPHPのDateTimeImmutableのインスタンスは、日時の加算で新しいインスタンスを返します。元のインスタンスの状態は変わりません。
    →イミュータブルです。
  • 想定していない更新を防ぐことができるためミュータブルより安全度があります
  • イミュータブル(immutable)は、不変という意味です。

イミュータブルのサンプルです。コードはPHPです。

<?php
//イミュータブルの例
$date1 = new DateTimeImmutable('2020-8-10 22:30:10');

// 3日後を求める
$date2 = $date1->modify("+3 day");
print $date2->format("Y/m/d"); // 2020/08/13

// 3日後を求める
$date3 = $date1->modify("+3 day");
print $date3->format("Y/m/d"); // 2020/08/13

3行目は、DateTimeImmutableのインスタンスを生成しています。
6行目は、$date1の3日後を求め、$date2に代入しています。
このときインスタンスの$date1は3日増えません(状態が変わらない)。3日増えたコピーを返します。

10行目は3行目の$date1の3日後を求め
結果として$date3に3日増えます。
→イミュータブルです。

関連の記事

静的型付けと動的型付けの違い
シャローコピーとディープコピーの違い

△上に戻る