TL

イミュータビリティ(不変性)

一度作った値を変更せず、変更が必要なときは新しい値を作る設計方針。副作用を減らし、並行処理でも安全に扱えます。

中級不変性関数型並行処理最終更新: 2026-06-06
TL;DR要点だけ先に
  • 1.イミュータビリティは値を後から変更せず、変更時は新しい値を作る設計方針です。
  • 2.予期せぬ書き換え(副作用)が減り、複数スレッドからの同時アクセスでも安全になります。
  • 3.関数型プログラミングの中核ですが、毎回コピーするコストとのバランスが必要です。

イミュータビリティとは

**イミュータブル(不変)な値とは、一度作ったら中身を変更できない値のことです。変更したい場合は、元を書き換えるのではなく、変更を反映した新しい値を作って差し替えます。逆に、後から中身を書き換えられる値はミュータブル(可変)**と呼びます。

  • 配列に要素を足したい → 元の配列を変えず、足した新しい配列を作る。
  • オブジェクトの1項目を直したい → コピーして該当項目だけ変えた新しいオブジェクトを返す。

「変えるのではなく、作り直す」。この発想の転換が不変性の核心です。

何がうれしいのか

不変にすると、値がいつの間にか書き換わる事故を根本から防げます。

  • 予期せぬ副作用が消える — ある関数に渡した値が、その関数の中で勝手に変わる心配がありません。
  • 追いやすい — 値が作られた後に変化しないので、「今この値は何か」を読むだけで把握できます。
  • 共有が安全 — 同じ値を複数箇所で参照しても、誰かの変更が他へ波及しません。
// ミュータブル:渡した配列が書き換わってしまう
function addBad(arr, x) {
  arr.push(x);      // 呼び出し元の配列を破壊
  return arr;
}

// イミュータブル:新しい配列を返し、元はそのまま
function addGood(arr, x) {
  return [...arr, x]; // コピーして末尾に追加
}

並行処理での安全性

複数のスレッドが同じデータを同時に書き換えると、競合状態(レースコンディション)という厄介なバグが生まれます。不変な値はそもそも書き換わらないため、この問題が起きません。

  • 可変データを共有すると、ロックなどの排他制御が必要になり、複雑さとバグの温床になります。
  • 不変データはロックなしで安全に共有できるため、並行・並列処理と非常に相性が良いです。
共有するなら不変に

スレッドやワーカー間でデータを渡すときは、不変にしておくと「誰がいつ書き換えたか」を疑わずに済みます。並行処理が絡む設計では、共有する値ほど不変に寄せるのが安全側の判断です。

関数型プログラミングとの関係

不変性は関数型プログラミングの中心的な考え方です。関数型では、入力から出力を計算するだけで外部の状態を書き換えない「純粋関数」を重視します。不変なデータは、この純粋さを自然に支えます。

  • 純粋関数 — 同じ入力なら必ず同じ出力。外を変えない。テストしやすい。
  • データを書き換える代わりに、変換した新しいデータを返すスタイルが基本になります。
// 元配列を変えずに、各要素を2倍した新配列を得る
const nums = [1, 2, 3];
const doubled = nums.map((n) => n * 2); // [2, 4, 6]、nums は不変

ミュータブルとの比較

どちらが常に優れているわけではなく、トレードオフがあります。

観点ミュータブル(可変)イミュータブル(不変)
変更方法その場で書き換える新しい値を作って差し替える
副作用起きやすい起きにくい
並行安全性排他制御が要るロックなしで安全
メモリ/速度上書きで効率的コピーのコストがかかる

コピーのコストと現実解

不変性の代償は、変更のたびにコピーが発生することです。巨大なデータを少し変えるだけで全体を作り直すと、メモリと時間を浪費します。

毎回フルコピーは重い

大きな配列やオブジェクトを高頻度で更新する場面では、丸ごとコピーがボトルネックになり得ます。実務では、変わらない部分を共有して差分だけ作る「永続データ構造」や、内部だけ一時的に可変にして最後に固める手法(イミュータブル系ライブラリの仕組み)で、コピーコストを抑えます。

  • ホットパス(高頻度・性能が重要な箇所)では、局所的に可変を許す判断も現実的です。
  • 境界の外へ渡す値は不変、内部の局所処理は可変も可」という使い分けがよく取られます。

まとめ

イミュータビリティは、値を変更せず必要なら作り直す設計方針です。予期せぬ書き換え(副作用)を防ぎ、並行処理でもロックなしで安全に共有でき、関数型プログラミングの土台にもなります。一方で毎回コピーするコストは無視できず、巨大データの高頻度更新では工夫が要ります。外へ公開する値は不変に、性能が要る局所は可変も検討——このバランス感覚が実務での落としどころです。

プログラミング Article

イミュータビリティ(不変性)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

不変性

比較で見る軸

難易度: intermediate / カテゴリ: プログラミング / タグ数: 3

導入後に効く点

予期せぬ書き換え(副作用)が減り、複数スレッドからの同時アクセスでも安全になります。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
intermediate
カテゴリ
プログラミング
タグ数
3

判断チェックリスト

  • 自社の用途が「不変性 / 関数型」に近いか確認する。
  • 強みである「イミュータビリティは値を後から変更せず、変更時は新しい値を作る設計方針です。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

不変性関数型並行処理不変性関数型並行処理
参考: 公式情報