レコード型

リストやタプル、配列といったデータ構造について説明してきましたが この他に、F#にはレコードというデータ構造があります。 レコードではいくつかの値を並べることでデータを表現し、 それぞれのデータに名前をつけられる点に特徴があります。 これはC言語でいえば構造体に相当するものですが F#ではC言語ライクな構造体の表現法は別にあります。 これについてはオブジェクト指向の部分で説明します。 基本的なレコードの構文は次のようになります
レコードの定義
type 型名 = { フィールド名1 : 型名1; ... ; フィールド名n : 型名n }
レコードの値の作成
{フィールド名1 = 式1; ... ; フィールド名n = 式n}
例として、商品名と値段のフィールドを持つjuice型の定義です。
レコード型の定義
type juice = {name : string;price : int};;
この型のデータを定義すると次のようになります。
レコード型の値
let my = {name = "Mellow Yellow";price = 110};;
let dp = {name = "Doctor Pepper";price = 120};;
また、既存のデータを使って新しいデータを定義することも出来ます。 構文は次の通りです
既存レコードからのレコード作成
{ 既存レコード with フィールド名1 = 式1; ... ; フィールド名n = 式n }
これを用いた例は次の通り
既存レコードからレコードを作る
let ab = { my with name = "Ambasa" };;
レコードから値を取り出すには、 レコード型の変数名.フィールド名のようにします。
レコードからの値の取り出し
> my.name;;
val it : string = "MellowYellow"
> ab.price;;
val it : int = 110
レコードに関して気をつけるべきことがあります。 それは、上記のような状態で次のような新しいレコードを定義したとします。
既存のレコードとかぶったフィールド名のレコード
type goods = {name : string;price : int};;
let my_oyatu = {name = "peranperan";price = 30};;
これは先ほど定義したjuice型と同じフィールド名を持っています。 この時、my_oyatuはjuice型ではなく、goods型となってしまいます。 つまり、新しく定義したレコードのフィールド名は 既存のレコードとかぶらないよう注意する必要があります。 このような点を考えると、ある程度の規模の開発でレコード型を使うのは 難しいのでは無いかと思います。 既存のレコードとフィールド名がかぶっていないことを意識しながら レコードを使うというのは大変だからです。 レコード型の値も、基本的には一度定義したら 値は変更できないのですが mutableキーワードをつけることで値を変更可能に出来ます。 この時、値を変更するには<-演算子を使います。
mutableなレコード
type human = {name:string;mutable age: int};;
let nobita = {name = "nobi nobita"; age = 11};;
let time_furosiki (x:human) = x.age <- x.age + 10;;
time_furosiki nobita;;
print_int nobita.age;;
名前も結婚で変わる可能性はありますが、 ここでは年齢だけが変更できるhumanクラスを定義しています。 wikiによると、のび太は10年ほど無人島に家出した経験があるらしいので このプログラムでは、タイムふろしきでのび太の年齢に補正をかけています。