イミュータブル いみゅーたぶる
不変性ミュータブル関数型プログラミング副作用スレッドセーフ値オブジェクト
イミュータブルについて教えて
簡単に言うとこんな感じ!
「一度決めたら絶対変えられない」ってこと!たとえば石に彫った文字みたいなもので、作った後に中身を書き換えることができないデータや設計のことだよ。「変えたい」なら新しいものを作り直すのがルールなんだ!
イミュータブルとは
イミュータブル(Immutable) とは、「変更不可能」を意味する英語で、一度作成したら中身を書き換えられないデータ・オブジェクト・インフラ構成などを指します。対義語は ミュータブル(Mutable) で、こちらは「変更可能」という意味です。
プログラミングの世界では、変数や配列・オブジェクトなどのデータが「作った後に中身を変えられるか」が設計の重要なポイントになります。イミュータブルなデータは作成後に状態が変わらないため、予測しやすく・バグが起きにくいという大きなメリットがあります。
近年ではクラウドインフラの分野でも「イミュータブルインフラストラクチャ」という概念が広まっており、サーバーを手で変更するのではなく「常に新しく作り直す」という運用スタイルとして注目されています。
イミュータブルとミュータブルの違い
| 特性 | イミュータブル(Immutable) | ミュータブル(Mutable) |
|---|---|---|
| 作成後の変更 | ❌ できない | ✅ できる |
| 安全性 | ◎ 高い(副作用なし) | △ 注意が必要 |
| 並列処理 | ◎ 安全(スレッドセーフ) | △ 競合が起きやすい |
| メモリ効率 | △ 変更のたびに新規生成 | ◎ 同じ領域を使い回せる |
| バグの追跡しやすさ | ◎ 状態が変わらないので追いやすい | △ どこで変わったか追いにくい |
覚え方
「イミュータブル = 石板(いしばん)」で覚えよう!
石に刻んだ文字は後から書き換えられない → 石板 = Immutable
ホワイトボードの文字は何度でも書き換えられる → ホワイトボード = Mutable
具体例:文字列の扱い
多くのプログラミング言語では文字列(String)はイミュータブルです。
// Javaの例(イミュータブルな文字列)
String s = "hello";
s = s + " world";
// ↑ 元の "hello" を変えているのではなく、
// "hello world" という【新しい文字列】を作って s に代入している!
// Pythonでのミュータブルな例(リスト)
mylist = [1, 2, 3]
mylist.append(4) # 同じリストに 4 を追加(中身を直接変更)
print(mylist) # → [1, 2, 3, 4]
# タプルはイミュータブル
mytuple = (1, 2, 3)
mytuple[0] = 99 # → エラー!変更できない
歴史と背景
- 1950〜60年代 — LISP などの関数型言語が登場。関数型プログラミングでは「データを変更しない」思想が根本にあり、イミュータブルの概念はここが起源
- 1980〜90年代 — Javaが
Stringクラスをイミュータブルとして設計。スレッドセーフ・セキュリティ・パフォーマンス(文字列プールの共有)を理由として採用 - 2000年代 — 並列・並行処理の重要性が増し、スレッドセーフなイミュータブル設計が再評価される
- 2010年代前半 — ScalaやHaskellなど関数型言語の台頭。Reactの登場(2013年)で「状態を直接変えない」思想がフロントエンドにも普及
- 2013年〜 — イミュータブルインフラストラクチャの概念が登場。DockerやKubernetesの普及により、「サーバーを変更するのではなく作り直す」運用が標準化
- 2015年〜現在 — RustやKotlin、SwiftなどモダンなプログラミングでデフォルトやオプションとしてImmutabilityを重視する設計が主流に
イミュータブルインフラストラクチャとの関係
ソフトウェアのデータだけでなく、サーバーやインフラ構成にもイミュータブルの考え方が広がっています。
イミュータブルインフラのメリット:
- 環境の一貫性 — 本番・ステージング・開発で同じイメージを使うため「自分の環境では動いたのに」問題が激減
- ロールバックが簡単 — 問題が起きたら古いイメージに戻すだけ
- セキュリティ向上 — サーバーの状態が積み重ならないため、設定ミスや不正な変更が残らない
プログラミング言語ごとのImmutability対応
| 言語 | イミュータブルの仕組み |
|---|---|
| Java | String・final・record(Java 16+) |
| Python | タプル(tuple)・frozenset |
| JavaScript | const(再代入不可)・Object.freeze() |
| Kotlin | val(再代入不可)・data class |
| Rust | デフォルトで全変数が不変(mutで可変にする) |
| Scala | val・コレクション操作は新オブジェクトを返す |
| Go | 構造体コピーによる不変パターン |
Rustの設計思想(最も徹底した例)
// Rustではデフォルトで変更不可
let x = 5;
x = 10; // → コンパイルエラー!
// 変更したいなら明示的に mut をつける
let mut y = 5;
y = 10; // OK
Rustは「変更可能なほうが例外」という設計で、イミュータブルを言語レベルで強制する代表例です。
関連する用語
- 関数型プログラミング — 副作用を排除し、データを変更しない設計スタイル。イミュータブルの思想的ルーツ
- 副作用 — 関数が外部の状態を変更してしまうこと。イミュータブルにより防げる
- スレッドセーフ — 複数の処理が同時実行されても安全なこと。イミュータブルはこれを保証しやすい
- イミュータブルインフラストラクチャ — サーバーを変更せず作り直す運用手法
- Docker — コンテナ技術。イミュータブルインフラの代表的なツール
- 値オブジェクト — DDDの設計概念。イミュータブルな設計が推奨されるオブジェクト
- Kubernetes — コンテナオーケストレーション。イミュータブルなデプロイの中心的プラットフォーム