SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

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

F#によるオブジェクト指向プログラミングの基礎

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

(3)valキーワード

 letで宣言されたフィールドはコンストラクタ内で宣言・定義されなくてはなりませんが、フィールドによっては必ずしもその場で定義ができるとは限りません。そこで、コンストラクタ内で、まだ定義できないフィールドを宣言するには、letの代わりにvalというキーワードを使用します。letでバインドされたフィールドは常にprivateであり、クラスのメソッドもしくはプロパティ経由でのみアクセスできます。対して、valで宣言されるフィールドはデフォルトでpublicになるため、クラスの外からフィールドを呼ぶ必要がある場合には、valを使用する必要があります。

【構文】valによるフィールドの宣言
[static] val [mutable] [アクセス修飾子] フィールド名 : 型

 プライマリコンストラクタを持つクラスでvalでフィールドを宣言する場合には、[<DefaultValue>]属性をつける必要があります。プライマリコンストラクタ内でvalを宣言する際にはvalはmutableキーワードとセットで使用される必要があります。

[リスト5]valによるフィールドの宣言
type testClass1(a1 : int, b1 : int) =
    let a = a1 + b1
    let mutable c = 3
    let mutable b = a1 * b1
    [<DefaultValue>] val mutable d : int
    [<DefaultValue>] val mutable e : string
    do printf "%d, %d" a b;;

let testClass1= new testClass1(4, 5)
//cはletで宣言されていてprivateなのでアクセスできない。
//testClass1.c <- 5
//dはvalで宣言されているので大丈夫。
testClass1.d <- 5;;

 ▼

type testClass1 =
  class
    new : a1:int * b1:int -> testClass1
    val mutable d: int
    val mutable e: string
  end

> 9, 20
val testClass1 : testClass1

(4)セルフ識別子

 セルフ識別子は、C#のthisにあたるものです(注1)。現在のインスタンスを表すときにthis ではなくここで指定した識別子を使用できるようになります。このとき、asキーワードに続き、コンストラクタパラメータの後に指定したセルフ識別子はクラス内で有効になります。

[リスト6]セルフ識別子としてKoreを指定
type testClass(testparam) as kore =
    let teststr = testparam
    //実行中のオブジェクトを表す識別子koreでtestClass内のメソッドを指定
    do kore.testMethod()
    //member行はメソッドを宣言しています。
    //メソッド名の前にメソッド内でのみ有効なセルフ識別子(this)を指定
    member this.testMethod() =
       printf "test self identifier : %s" teststr
//インスタンス作成
let testItem = testClass("aaa")
//メソッド呼び出し
testItem.testMethod();;

 ▼

//インスタンス作成に伴うプライマリコンストラクタの処理
test self identifier : aaa
//メソッド呼び出しによる処理
test self identifier : aaa

type testClass =
  class
    new : testparam:string -> testClass
    member testMethod : unit -> unit
  end
val testItem : testClass

 self identifierに対応する日本語として、セルフ識別子と書きましたがマイクロソフトによる正式な日本語名称は不明です。

(5)ジェネリック型

 F#では、ジェネリックな型のパラメータはアポストロフィ(')を前につけて、'a、'Tなどのように表されます。

[リスト7]パラメータがジェネリックな関数
let testGetFst (a, b) = a;;

 ▼

val testGetFst : 'a * 'b -> 'a

 F#でコードをジェネリックにしたいとき、大抵の場合はコンパイラによる型推論もしくは、自動ジェネリック化機能によって暗黙的にジェネリックになります。自動ジェネリック化機能というのは、コンパイラが提供されたパラメータから型推論できず、またそれらが他の要素の型に依存することがないと判断したときに、ファンクションが複数の種類の型のパラメータで機能するように一般化(ジェネリック化)することです。

 例えば、上記の例は2つの要素を持つ組(タプル)を与えられたときに常に1つ目の要素を返す関数ですが、このとき、コンパイラは2つのパラメータが他の要素の型に依存することがないと判断し、パラメータをジェネリック化しています。

 しかし、あえて曖昧さをなくすため明示的に指定したい場合には、山括弧(<>)を使用して指定することが可能です。下記のリスト8は、プライマリコンストラクタが受け取る2つのパラメータがジェネリックであるクラスの例です。クラス名の後に山括弧でパラメータを指定します。

[リスト8]ジェネリック型パラメータのクラス
type testClass<'a, 'b> (x : 'a, y : 'b) =
    let x0 = x
    let y0 = y
    do printfn "%A %A" x0 y0
//string型とint型のパラメータで初期化
let testItem = testClass<string, int> ("aaa", 5)
//int型とfloat型のパラメータ3で初期化
let testItem2 = testClass<int, float> (3, 3.0);;

 ▼

"aaa" 5
3 3.0

type testClass<'a,'b> =
  class
    new : x:'a * y:'b -> testClass<'a,'b>
  end
val testItem : testClass<string,int>
val testItem2 : testClass<int,float>
補足

 Automatic generalizationに対応する日本語として、自動ジェネリック化と書きましたがマイクロソフトによる正式な日本語名称は不明です。

次のページ
アクセス修飾子

この記事は参考になりましたか?

C#プログラマのためのF#入門連載記事一覧

もっと読む

この記事の著者

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

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4600 2009/12/16 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー