成らぬは人の為さぬなりけり

エンジニアライフをエンジョイする為のブログ

Scala2.10の新機能を勉強する その2 ImplicitClass

前回のつづきで、
今日はScala2.10のImplicitClassをやってみたいと思います。

環境

ImplicitClassって?

簡単に言うと、ImplicitConversionを楽に書ける機能、
と理解して良いんでしょうかね?
SIP-13 - Implicit classes - Scala Documentation

つまり

  • 変換する型の定義
  • 変換するメソッドの定義

が一発で書ける。

とりあえず、書いてみます。

ImplicitClassを書いてみる


こんな感じで書いてみました。
「HalfInt」はclassの定義とimplicit defの定義が必要ですが、
「DoubleInt」はimplicit classの定義だけで済んでいます。
これは確かに完結で良い。
ただ、これ、同じようにコンパイルされるんだろうか?
という事で、jadってみます。

package implicitclass;

import scala.Function0;
import scala.Predef$;
import scala.runtime.*;

// Referenced classes of package implicitclass:
//            ImplicitClass_01$

public final class ImplicitClass_01
{
    public static class HalfInt
    {

        public int half()
        {
            return i / 2;
        }

        private final int i;

        public HalfInt(int i)
        {
            this.i = i;
            super();
        }
    }

    public static class DoubleInt
    {

        public int _mthdouble()
        {
            return i * 2;
        }

        private final int i;

        public DoubleInt(int i)
        {
            this.i = i;
            super();
        }
    }

    public static class delayedInit.body extends AbstractFunction0
    {

        public final Object apply()
        {
            Predef$.MODULE$.println(BoxesRunTime.boxToInteger($outer.DoubleInt(1)._mthdouble()));
            Predef$.MODULE$.println(BoxesRunTime.boxToInteger($outer.toHalfInt(1).half()));
            return BoxedUnit.UNIT;
        }

        private final ImplicitClass_01$ $outer;

        public delayedInit.body(ImplicitClass_01$ $outer)
        {
            if($outer == null)
            {
                throw new NullPointerException();
            } else
            {
                this.$outer = $outer;
                super();
                return;
            }
        }
    }


    public static void main(String args1[])
    {
        ImplicitClass_01$.MODULE$.main(args1);
    }

    public static void delayedInit(Function0 function0)
    {
        ImplicitClass_01$.MODULE$.delayedInit(function0);
    }

    public static String[] args()
    {
        return ImplicitClass_01$.MODULE$.args();
    }

    public static void scala$App$_setter_$executionStart_$eq(long l)
    {
        ImplicitClass_01$.MODULE$.scala$App$_setter_$executionStart_$eq(l);
    }

    public static long executionStart()
    {
        return ImplicitClass_01$.MODULE$.executionStart();
    }

    public static HalfInt toHalfInt(int i)
    {
        return ImplicitClass_01$.MODULE$.toHalfInt(i);
    }

    public static DoubleInt DoubleInt(int i)
    {
        return ImplicitClass_01$.MODULE$.DoubleInt(i);
    }
}

ほぼ同じようにコンパイルされてるっぽい(?)

ImplicitClassを切り出してみる

次にImplicitClassを切り出してみます。

コメントにも書いてありますが、
implicit classをトップレベルで書けないようです。
以下のようなエラーになりました。

[error] /Users/xxxx/workspace/scala-samples/scala-2.10-sample/src/main/scala/implicitclass/ImplicitClass_02.scala:10: `implicit' modifier cannot be used for top-level objects
[error] implicit class TripleInt(i: Int) {
[error]                ^
[error] one error found
[error] (compile:compile) Compilation failed

importに関しては、implicit defで定義する時も同じような使いかたをするだろうし、
あまり変わらないかな??

今日は、ここまでにします。
次回はValueClassに挑戦。
(内容薄いですが、メモなので、、、、(逃