まずはお約束のHelloWorld
前回は、Eclipseプロジェクトによって開発された新プログラミング言語「Eclipse Xtend」の概要と、Eclipseへのインストール方法を解説しました。今回は、Xtendの特徴的な機能のうちのいくつかを紹介します。
まずはその前に、お約束のHelloWorldプログラムを作ってみましょう。Xtendを使う場合には、通常のJavaアプリケーションと同じようにプロジェクトを作成し、ライブラリとして関連するjarファイルを追加します。jarファイルはEclipseのプラグインフォルダ(EclipseがC:\eclipseにインストールされている場合には、C:\eclipse\plugins)にあります。基本的な機能であれば「org.eclipse.xtext.xtend2.lib_xxxx.jar」と「org.eclipse.xtext.xbase.lib_xxxx.jar」(xxxxはバージョン番号)があればOKです。
プログラムのソースファイルも、Javaと同様にsrcフォルダにパッケージを作成して配置します。新規ファイル作成ウィザードで[Xtend]-[Xtend Class]を選択すれば、クラスファイルの雛形を作成することができます。ファイルの拡張子は.xtendです。
HelloWorld.xtendの例を以下に示します。
Javaとの大きな違いは、行末にセミコロンが付かない点です。メソッドの定義には「def」を、変数宣言には「var」または「val」を使用します。valの場合は変更負荷の変数になります。変数の型宣言は省略することができますが、これは型推論によってコンパイル時に自動で型付けされるだけで、Xtendはあくまでも静的型付けの言語です。メソッドの戻り値は最後に評価した式の値になるので、「return」キーワードは省略することができます。
main()メソッドはJavaと同様にstatic修飾子を付けて作成します。実行方法もJavaプログラムと同様で、ファイル名を右クリックして[実行]-[Javaアプリケーション]を選択すれば実行できます。
このプログラムはJavaコードにコンパイルされ、xtend-genフォルダ以下に「HelloWorld.java」が作成されます。これは通常のJavaファイルとまったく変わらないものなので、Javaコードから呼び出すこともできます。
クロージャ
Xtendではクロージャを使うことができます。クロージャを作成するための文法は『[ 引数リスト | 処理内容 ]』の形で定義し、apply()メソッドによって実行します。次のコードは、文字列を引数として受け取り、その内容を表示するクロージャの例です。apply()に渡された文字列(この場合は「Hello!」)が出力されます。
クロージャを引数にとるメソッドや、戻り値としてクロージャを返すメソッドを作ることもできます。クロージャの型は『(引数の型のリスト) => 文字列の型』のように記述します。次のmyFunc1()メソッドは、第2引数としてクロージャを受け取るメソッドの例です。第1引数に渡されたリストの各要素に対して、それぞれクロージャの処理を実行します。
myFunc1()を実行するコードは次のようになります。namesに対するメソッド呼び出しのように見えますが、実際にはnamesがmyFunc1()の第1引数として扱われます。これは後述する拡張メソッドの機能によるものです。1つ目の呼び出しではtoUpperCase()、2つ目の呼び出しではtoLowerCase()を実行するクロージャを渡しているので、実行すればそれぞれ「[TARO, JIRO]」、「[taro, jiro]」が出力されます。
次の例は戻り値としてクロージャを返すメソッドmyFunc2()を定義したものです。引数を文字列にとり、『"Hello " + name + "!"』を実行するクロージャが返されます。
myFunc2()から返されたクロージャは、通常通りapply()メソッドを呼び出すことで実行できます。
拡張メソッド
Xtendには拡張メソッドと呼ばれる機能が用意されています。これは、独自に定義したメソッドをあたかも既存のクラスのメソッドであるかのように呼び出すことができる仕組みです。次のに示す例は、hello()をStringの拡張メソッドとして定義したものです。
このhello()メソッドは、次のようにあたかも第1引数の型であるStringクラスのメソッドであるかのように呼び出すことができます。
もちろん、これは実際にStringにhelloメソッドが追加されたわけではなく、内部では『this.hello("Gihyo")』の呼び出しとして扱われます。前述のクロージャの例でも、この拡張メソッドの仕組みを利用して、第1引数の型を呼び出し元のレシーバであるかのように使っています。
プロパティへのアクセス
Xtendのオブジェクトがもつプロパティに対しては、『変数名.プロパティ名』という形式で、アクセッサメソッド経由のアクセスを行うことができます。例えば、次のような2つのプロパティと、それに対するアクセッサメソッド、そして面積を計算するgetArea()メソッドを持つクラスを考えてみます。
このSquareクラスのインスタンスsquareを作った場合、widthとheightという2つのプロパティには、それぞれ『square.width』、『square.height』の形式でアクセスできるということです。Javaコードにコンパイルされる際には、このアクセスはsetWidth()やgetWidth()を経由したものに置き換えられます。以下に使用例を示します。
もうひとつ注目したいのが、引数を取らないメソッドも、プロパティへのアクセスと同じように呼び出すことができるという点です。例えばgetArea()メソッドは次のように()を省略して呼び出すことができます。
また、メソッド名がgetXXXX()という形式の場合、次のように"get"を省略した形で呼び出すことも可能です。
演算子オーバーロード
XtendではC++のように演算子をオーバーロードして独自の演算を定義できます。演算子オーバーロードを行うには、メソッド名の先頭に"operator_"をつけた特別なメソッドを定義します。たとえば"operator_plus"というメソッドを定義することで、+演算子の動作を定義することができます。-演算子の場合は"oparator_minus"です。演算子とメソッド名の対応はこのページにまとめられています。
次に示すVector2Dクラスでは、+、-、*の演算子をオーバーロードしています。*演算子に対応するメソッド名は"operator_multiply"です。new()メソッドはコンストラクタを表します。また、メソッドをオーバーライドする場合にはoverride修飾子を付けて宣言します。
このように演算子に対応したメソッドを定義しておくと、次に示すようにそれぞれの演算子を使った演算が行えるようになります。
ここで紹介した以外にも、JavaにはないXtendにはさまざまな機能が用意されています。まだ開発途上の言語ではありますが、Javaアプリケーション開発の効率を上げるツールのひとつとして見れば将来性のある言語だと思います。ぜひ活用してみてください。