- 手軽なスクリプト言語としてのF#
- 手軽なスクリプト言語としてのF# その2
- 手軽なスクリプト言語としてのF# その3
- 手軽なスクリプト言語としてのF# その4
- 手軽なスクリプト言語としてのF# その5
- 手軽なスクリプト言語としてのF# その6
- 手軽なスクリプト言語としてのF# その7
8回目です。次はレコードというやつをやってみようと思います。ここを見てる人はC#をやったことがあるという前提でエントリ書いてるのですが、C#でいう単純なプロパティを持ったクラスです。メソッドとかも持たせようと思えば持たせることが出来ます。
定義方法は簡単で以下のような感じになります。
type レコード名 = { フィールド名 : フィールドの型;フィールド名 : フィールドの型;フィールド名 : フィールドの型;... }
フィールドの定義は複数行にわけて書くことも出来ます。フィールドの定義を1行に1フィールドにする場合はセミコロン省略で書いてOKです。
type レコード名 = { フィールド名 : フィールドの型 フィールド名 : フィールドの型 フィールド名 : フィールドの型 .... }
ということでさくっと名前と年齢を持つ人間を表すレコードを作ってみようと思います。
// Personレコードの定義 type Person = { Name : string; Age : int } // Personレコードの作成 let p = { Name = "田中"; Age = 48 } // こんな風にレコード名を明示することも出来る let p2 = { Person.Name = "大田"; Age = 29 } // レコードのフィールドの値は.を使ってアクセスできる printfn "%s さんは %d 歳です" p.Name p.Age printfn "%s さんは %d 歳です" p2.Name p2.Age
実行結果は以下のようになります。
田中 さんは 48 歳です 大田 さんは 29 歳です
レコードの作り方が特徴的ですね。 { フィールド名 = 値; ... }で作れる上に、フィールドの名前と型あたりからF#が必至に空気を読んで、どのレコードか探してきてくれるのが印象的です。まったく同じフィールドを持つレコードがある時に備えてp2でやってるようにレコード名を明示する方法もあります。
さらに、レコードの値をコピーする方法も用意されています。 { 元になるレコード with フィールド名 = 値; ... }のような形になります。これも小さなプログラムで動きを確認してみましょう。
// Personレコードの定義 type Person = { Name : string; Age : int } // Personレコードの作成 let p = { Name = "田中"; Age = 48 } // pの値をもとに値の変わるフィールドだけ設定しなおす let newTanaka = { p with Age = 100 } // 印字 printfn "%s さんは %d 歳です" p.Name p.Age printfn "%s さんは %d 歳です" newTanaka.Name newTanaka.Age
pの値をもとにnewTanakaを作ってます。実行結果は以下のようになります。newTanakaで再定義したAgeの値が反映されてるのがわかると思います。
田中 さんは 48 歳です 田中 さんは 100 歳です
さて、次はレコードにメソッドを定義してみようと思います。メソッドの定義の仕方は以下のような感じで出来ます。
type レコード名 = { フィールドの定義 } with member 自己識別子.メソッド名(引数) = 処理の中身 member 自己識別子.メソッド名(引数) = 処理の中身
自己識別子ってなんぞや?という感じですが、C#でいうところのthisに該当するものです。F#ではすきに名前を付けることができます。早速、自己紹介をするメソッドを追加してみようと思います。
// Personレコードの定義 type Person = { Name : string; Age : int } with member this.Greet() = printfn "私の名前は %s で %d 歳です" this.Name this.Age // Personレコードの作成 let p = { Name = "田中"; Age = 48 } // メソッドを呼んでみる p.Greet()
今回は引数を受け取らないメソッドを定義していますが、タプルを渡す関数と同じ要領で複数の値を渡すことができます。
なんか段々オブジェクト指向ちっくになってきました。