Scala2.10の新機能を勉強する その3 ValueClass
前回に引き続き、
Scala2.10の新機能を勉強していきます。
今回のテーマは「ValueClass」です。
ValueClassって?
ありがたい事に公式ドキュメントを日本語訳して頂いているページがあります。
値クラスと汎用トレイト - Scala Documentation
こちらによると、
実行時のオブジェクト割り当てを回避する
と書いてあります。
つまりどういう事なんでしょうか?
オブジェクトの生成を行わない?
???
とりあえず、書いてみようかと思います。
ValueClassを定義する
ValueClassは以下の特徴があります。
- AnyValを継承する
- ただひとつのpublicなvalパラメータを持てる
- 汎用トレイトのみ拡張できる
- defは定義できるが(上記以外の)val、var,内部trait・class・obejctは定義できない
順番に全部試してみます。
まずは、Double.scalaの3行目。
- AnyValを継承する
- ただひとつのpublicなvalパラメータを持てる
次に4〜12行目。
- defは定義できるが(上記以外の)val、var,内部trait・class・obejctは定義できない
これらを書いてみました。
ここまでで、まずは、ValuClass_01.scalaの4行目は実行できます。
ここまでの状態でValueClass_01をjadってみました。
… public final class ValueClass_01 { public static class delayedInit.body extends AbstractFunction0 { public final Object apply() { Predef$.MODULE$.println(BoxesRunTime.boxToInteger(Double$.MODULE$.double$extension(10))); return BoxedUnit.UNIT; } public delayedInit.body(ValueClass_01$ $outer) { } } … }
DoubleクラスのAnyValをはずしてコンパイルすると、以下のようになります。
… public final class ValueClass_01 { public static class delayedInit.body extends AbstractFunction0 { public final Object apply() { Predef$.MODULE$.println(BoxesRunTime.boxToInteger((new Double(10))._mthdouble())); return BoxedUnit.UNIT; } public delayedInit.body(ValueClass_01$ $outer) { } } … }
これを見ると前者は「new Double(10)」していない事がわかります。
「オブジェクト割り当てを回避する」というのはこういう事なんですね。
なるほど。
汎用トレイトを拡張する
汎用トレイト、という言葉を初めて聞きました。
汎用トレイトとは、
- Anyを拡張する
- メンバとしてdefを持つ
- 初期化を一切行わない
というトレイトの事だそうです。
上記の例で言うと、「Hoge」トレイトになります。
汎用トレイトを拡張すると
メモリー割り当てのオーバーヘッドを伴うようにもなる
と書かれています。
では、上記例のValueClass_01をjadってみたいと思います。
… public final class ValueClass_01 { public static class delayedInit.body extends AbstractFunction0 { public final Object apply() { Predef$.MODULE$.println(BoxesRunTime.boxToInteger(Double$.MODULE$.double$extension(10))); Predef$.MODULE$.println((new Double(10)).hoge()); return BoxedUnit.UNIT; } public delayedInit.body(ValueClass_01$ $outer) { } } … }
なるほど、「new Double(10)」されていますね。
※補足
上記例の「Ten」クラスですが、
「ただひとつのpublicなval」が「パラメータ」では無いので、
コンパイルエラーになりました。という例です。
Implicit Classと組み合わせてみる
ImplicitClassと組み合わせるとInplicitConversion時にオーバーヘッドなく使えるっぽい。
上記例では、「Triple」の例がこれに該当します。
ちょっとつかれてきたので、jadった結果は割愛しますが、
今までの内容を加味すると、確かにオーバーヘッドなく使えるんだろうな、とおもいます。
次回
次回はValueClassの
- メモリ割り当てが必要になるとき
- 制約
について勉強したいと思います。