Upload
hideki-kishida
View
2.388
Download
5
Embed Size (px)
DESCRIPTION
Indroduction Xtend, Extending Java, Statically typed, Closure, Extension method
Citation preview
● Eclipseからリリースされている
● 新しいJVM言語
● 少ない学習コストで
● 静的型で安全に
● Javaをより簡潔に
● Javaをより強力に
Xtendとは
● Javaプロジェクトで一緒に使う
● Xtendクラス → Javaクラスに変換
● interface, enum, annotationなどは
全部Javaのまま
Xtendとは
Xtend == Java + α != 新言語
Javaのエクステンション
Xtendとは
class HelloXtend {def static void main(String[] args) {
println('Hello Xtend')}
}
Hello Xtend
import java.util.Listimport static extension java.util.Collections.*class HelloClosure {
def static void main(String[] _) {println(positiveOnly(newArrayList(1, 5, 2, -10, 4)))
}def static positiveOnly(List<Integer> values) {
values.filter [it > 0]}
}
Hello Closure
リアルタイムなJavaソース生成
● 静的型
● 高い表現力
● Javaの型システムをそのまま使える
● IDEによる賢い補完
Xtendのメリット
● 型推論
● プロパティアクセス
● 演算子オーバロード
● 全てが「式」
Javaをより簡潔に
● クロージャ
● 拡張メソッド
● 強力なswitch式
● マルチプル・ディスパッチ
● テンプレート式
● Xtend全体がJavaのシュガー
Javaをより強力に
● Scala使える状況ならScala使おう!
Scalaでいいんじゃん?
● Javaソースが必要なとき
(契約、GWT、etc...)
● Javaプログラマが
少ない学習コストで
今日からすぐに
開発/保守を効率化するとき
Xtend/いつ/なぜ?
● Eclipse + Xtend (☆Marketplace)
● 1. Javaプロジェクトを普通に作成
● 2. Xtend Classを作る
● 3. Quick Fixでライブラリを導入
● 4. あとはXtendクラスを書くだけ
● 5. 自動的にJavaソースに変換される
※ Mavenでもビルドできます
Xtendの開発環境
val List<String> names = getTheListOfNames() val names = getTheListOfNames()
※ 変数の型は省略できる
型推論~変数
for (String name : getTheListOfNames()) for (name : getTheListOfNames())
※ 変数の型は省略できる
型推論~forループ
def List<String> getTheListOfNames() { newArrayList("Tomte","Pippi","Carlson")}
def getTheListOfNames() { newArrayList("Tomte","Pippi","Carlson")}
※ リターン型は省略できる
型推論~リターン型
getTheListOfNames().map(String name | "Mr. "+name) getTheListOfNames().map(name | "Mr. "+name)
※ パラメータ型は省略できる
型推論~クロージャ・パラメータ
person.getName()person.name person.setName("Foo")person.name = "Foo" obj.compute()obj.compute
※ プロパティをより自然に扱える
プロパティ・アクセス
val apples = newArrayList(new Apple())val oranges = newArrayList(new Orange())val fruits = apples + oranges
※ 演算子の意味を多重定義できる
演算子オーバロード
e1 += e2 e1.operator_add(e2)e1 || e2 e1.operator_or(e2)e1 && e2 e1.operator_and(e2)e1 == e2 e1.operator_equals(e2)e1 != e2 e1.operator_notEquals(e2)e1 < e2 e1.operator_lessThan(e2)e1 > e2 e1.operator_greaterThan(e2)e1 <= e2 e1.operator_lessEqualsThan(e2)e1 >= e2 e1.operator_greaterEqualsThan(e2)e1 -> e2 e1.operator_mappedTo(e2)
演算子の種類(1)
e1 .. e2 e1.operator_upTo(e2)e1 + e2 e1.operator_plus(e2)e1 - e2 e1.operator_minus(e2)e1 * e2 e1.operator_multiply(e2)e1 / e2 e1.operator_divide(e2)e1 % e2 e1.operator_modulo(e2)e1 ** e2 e1.operator_power(e2)! e1 e1.operator_not()- e1 e1.operator_minus()
演算子の種類(2)
val data = if (file.exists) { fileContentsToString(file) } else { 'has no data' }
※ 文じゃないから評価結果が値になる
※ caseやtry~catchも式です
すべてが「式」
class Printer { def void print(Person person) { println(person.fullName) } def getFullName(Person p) { p.firstName + " " + p.lastName }}
クラスにメソッドを外部から追加する
イメージで呼び出せるようになる
拡張メソッド~ローカル拡張
class Printer { @Inject extension PersonExtension def print(Person person) { println( person.fullName ) }}
※ 外部定義された拡張をDIで適用する
拡張メソッド~Inject
import static extension java.util.Collections.*
静的拡張ライブラリを使える。
コレクションや文字列の拡張が便利。
高階関数+クロージャが超強力!
拡張メソッド~static import
val names = people.map [ p | p.name ]
※ コレクション処理がとても簡単に
クロージャ(1)~ブロック
val predicate =[Person person | "Hans" == person.name]
people.filter(predicate)
※ ラムダ式で生成した関数を
高階関数に渡せる
クロージャ(2)~ラムダ式
people.filter[ Person p | "Hans" == p.name ]people.filter[ p | "Hans" == p.name ]people.filter[ "Hans" == it.name ]people.filter[ "Hans" == name ]
※ 型推論や暗黙itパラメータで簡略化
クロージャ(3)~簡略化
html [ head [ title [$("XML encoding with Xtend")] ] body [ h1 [$("XML encoding with Xtend")] p [$("this dsl can be used as alternative to XML")]
※ BuilderなどのDSLとしても有効
クロージャ(4)~Builder DSL
val fullName = '''Name: «p.firstName» «p.lastName»''' def getFullName(Person p) '''
Fist name: «p.firstName»Last name: «p.lastName»
'''
※ テンプレート文字列を簡単に作れる
※ IF/FORなどの制御構造も埋め込める
テンプレート式
val Shape shape = ...val desc = switch (shape) { Rectangle case shape.width == shape.height : "Square ("+shape.width+")" Rectangle : "Rectangle ("+shape.width+" x "+shape.height+")" Circle : "Circle ("+shape.diameter+")" default : "Don't know"}
※ 型ガードと条件検査を同時にできる
Switch式
def example() { val Shape s = new Rectangle() println(s.label)}def dispatch label(Shape s) { "some shape"}def dispatch label(Rectangle r) { ← "a rectangle"}
※ 実行時の型でメソッドが選択される
マルチプル・ディスパッチ
● 言語機能もIDEも、まだ少し力不足
● 開発が活発です
● ちょっと足りないなと思うものも、
次々に実装されていきます
どんどん進化中!
● 開発者がイケメン
● Sven Efftingeさん素敵です
+1
● 少ない学習コストで
● 静的型で安全に
● Javaをより簡潔に
● Javaをより強力に
Xtendのまとめ