CodeZine(コードジン)

特集ページ一覧

F#のオブジェクト式とミュータブルオブジェクト

C#プログラマのためのF#入門(6)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/05/10 14:00

目次

ミュータブル(可変)/イミュータブル(不変)オブジェクト

 以前、F#は非純粋関数型言語であると説明しましたが、では非純粋関数型言語ではどのように値の状態を変更するかということについて説明します。

 まず基本となる、イミュータブル、ミュータブルの概念から説明します。

 既存の.NET言語の変数はほとんどデフォルトでミュータブルです。一方、F#のオブジェクトは基本的にデフォルトではイミュータブル(不変)であり、一度値が決められたらそれを変更することができません。

 マルチスレッド環境では、ミュータブル(可変)なデータは、複数のスレッドによって変更される可能性があり、管理が難しいです。それに対し、イミュータブルなデータはコード内のプログラムとその機能を強力に結びつけるため、デバッグが簡単になる傾向があります。イミュータブルなデータを用いたプログラムができることは結果を戻すことのみなので、関数やメソッドにおいてインプット・アウトプットの分析などが簡単だからです。オブジェクトがイミュータブルである場合、オブジェクトの複製は参照の複製であり、メモリが節約できたり、プログラムが速く実行できるというメリットもあります。

 また、データがイミュータブルなオブジェクトで表現されている場合、排他制御の心配をしなくてもよく、ミュータブルなオブジェクトより比較的スレッドセーフであると言えます。

ミュータブルなオブジェクトと参照セル

 では、なぜF#にはオブジェクトをミュータブルなオブジェクトとして定義する機能があるのでしょうか。

 それは、ミュータブル変数はプログラムの実行中に変数の値を変えることができるなど、時にプログラムに柔軟性を与えるからです。また、他.NET言語と相互運用するためにも、F#においてミュータブル変数は不可欠な機能でもあります。

 オブジェクトをミュータブル変数として定義するにはmutableキーワードを使用します。

[構文]ミュータブル変数の定義
let mutable 変数名 = 値

 正確には「変数」イコール「ミュータブル(可変)」なのですが、ここでは解説上分かりやすくするため、ミュータブル変数という表現を使用したいと思います。

 以下の例では、xをミュータブル変数として宣言し、デフォルトの値1に10を追加しています。見慣れない“<-"は代入用の演算子で、"x + 10"をxに代入することを意味します。

[リスト2]ミュータブル変数の束縛
let mutable x = 1
x <- x + 10
x;;

 ▼

val mutable x : int = 11

 F#においてもう1つ、値を一度定義された後に変更する方法があります。参照セルと呼ばれるものです。一般的に他の言語でポインタとして知られる機能に似た機能です。ref演算子を使用して定義された値はコピーされ初期値となり、同時に値への参照が作成されます。つまり、参照セルはアドレスだけではなく、値も保持します。参照先の値が変化するたびに値のコピーが作成されます。

 ミュータブル変数と参照セルは大変似た機能を持ちますが、クロージャを生成する式(ラムダ式、シーケンスなど)ではミュータブル変数は使用できず、参照セルのみ使用可能です(ミュータブル変数を定義しようとするとコンパイラはエラーを返します)。

[構文]参照セルの定義
let 変数名 = ref  値

 参照セルの主要機能を解説します。

 以下はmutableなオブジェクトと参照セルの機能の違いを比較する例です。

[リスト3]Mutable変数操作
let mutable xMut = 3;;  //※1
xMut <- xMut + 1;;  //※2
xMut;;

let mutable yMut = xMut;;  //※3
yMut <- yMut + 1;;  //※4
yMut;;
xMut;;

 ▼

val mutable yMut : int = 4


>
val it : unit = ()

>
val it : int = 5

> val it : int = 4


val mutable xMut : int = 3


>
val it : unit = ()

>
val it : int = 4
> 

 リスト3と以下の図を見てください。

Mutableなオブジェクトの操作
Mutableなオブジェクトの操作

 xMutというint型(値型)のミュータブル変数に3をバインド(※1)します。

 xMutに1を追加すると、xMutは4になります(※2)。ミュータブル変数としてyMutにxMutをバインドすると、yMutもまたint型(値型)になり4という値がバインド(※3)されます。

 ここで、yMutに1を追加する(※4)と、yMutは5になりますが、xMutへの操作は行われないため、xMutの値は4のままです。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:C#プログラマのためのF#入門

もっと読む

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 星山 仁美(ホシヤマ ヒトミ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5