プログラミング基礎概念

イミュータブル いみゅーたぶる

不変性ミュータブル関数型プログラミング副作用スレッドセーフ値オブジェクト
イミュータブルについて教えて

簡単に言うとこんな感じ!

「一度決めたら絶対変えられない」ってこと!たとえば石に彫った文字みたいなもので、作った後に中身を書き換えることができないデータや設計のことだよ。「変えたい」なら新しいものを作り直すのがルールなんだ!


イミュータブルとは

イミュータブル(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年代JavaString クラスをイミュータブルとして設計。スレッドセーフ・セキュリティ・パフォーマンス(文字列プールの共有)を理由として採用
  • 2000年代 — 並列・並行処理の重要性が増し、スレッドセーフなイミュータブル設計が再評価される
  • 2010年代前半ScalaHaskellなど関数型言語の台頭。Reactの登場(2013年)で「状態を直接変えない」思想がフロントエンドにも普及
  • 2013年〜イミュータブルインフラストラクチャの概念が登場。DockerKubernetesの普及により、「サーバーを変更するのではなく作り直す」運用が標準化
  • 2015年〜現在RustKotlinSwiftなどモダンなプログラミングでデフォルトやオプションとしてImmutabilityを重視する設計が主流に

イミュータブルインフラストラクチャとの関係

ソフトウェアのデータだけでなく、サーバーやインフラ構成にもイミュータブルの考え方が広がっています。

ミュータブル vs イミュータブル インフラ ミュータブルインフラ(従来) サーバーを立てる (物理 / 仮想マシン) 設定変更・パッチ適用 ← ここで状態が変わる! 同じサーバーを使い続ける (構成が複雑化しやすい) イミュータブルインフラ(現代) イメージ(テンプレート)を定義 (Dockerfile / AMI など) 新しいイメージを作成・デプロイ ← 既存は一切変更しない! 古いサーバーを破棄して入れ替え (常にクリーンな状態)

イミュータブルインフラのメリット:

  • 環境の一貫性 — 本番・ステージング・開発で同じイメージを使うため「自分の環境では動いたのに」問題が激減
  • ロールバックが簡単 — 問題が起きたら古いイメージに戻すだけ
  • セキュリティ向上 — サーバーの状態が積み重ならないため、設定ミスや不正な変更が残らない

プログラミング言語ごとのImmutability対応

言語イミュータブルの仕組み
JavaStringfinalrecord(Java 16+)
Pythonタプル(tuple)・frozenset
JavaScriptconst(再代入不可)・Object.freeze()
Kotlinval(再代入不可)・data class
Rustデフォルトで全変数が不変(mutで可変にする)
Scalaval・コレクション操作は新オブジェクトを返す
Go構造体コピーによる不変パターン

Rustの設計思想(最も徹底した例)

// Rustではデフォルトで変更不可
let x = 5;
x = 10;  // → コンパイルエラー!

// 変更したいなら明示的に mut をつける
let mut y = 5;
y = 10;  // OK

Rustは「変更可能なほうが例外」という設計で、イミュータブルを言語レベルで強制する代表例です。


関連する用語

  • 関数型プログラミング — 副作用を排除し、データを変更しない設計スタイル。イミュータブルの思想的ルーツ
  • 副作用 — 関数が外部の状態を変更してしまうこと。イミュータブルにより防げる
  • スレッドセーフ — 複数の処理が同時実行されても安全なこと。イミュータブルはこれを保証しやすい
  • イミュータブルインフラストラクチャ — サーバーを変更せず作り直す運用手法
  • Docker — コンテナ技術。イミュータブルインフラの代表的なツール
  • 値オブジェクトDDDの設計概念。イミュータブルな設計が推奨されるオブジェクト
  • Kubernetes — コンテナオーケストレーション。イミュータブルなデプロイの中心的プラットフォーム