Hatena::Groupocaml-nagoya

yoshihiro503の関数的日記

2012-02-14 (Tue)

Javaでブロック式

| 21:27 | Javaでブロック式 - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - Javaでブロック式 - yoshihiro503の関数的日記

Javaで2つのコンストラクタ定義して、一方から他方を呼びたいときにはthis(a,b,c)とアクセスするが、必ず最初に書かなければならないという制約がある。こういうときScalaOCamlのようなlet式 or ブロック式が欲しくなる。

例えば次の例を見てほしい。

class C {
  public C(Person p) {
    ...
  }

  public C() { //こう書きたい
    Person imai = new Person("imai"); //デフォルトのPerson
    imai.setCurrentAddress("名古屋"); //現在の住所は"名古屋"
    this(imai); //ここでコンパイルエラー (Constructor call must be the first statement in a constructor)
  }
}

こういうときScalaならブロックを使って次のようにかける。

class C {
  def this(p : Person) = {
    ...
  }

  def this() = {
    this {
      Person imai = new Person("imai");
      imai.setCurrentAddress("名古屋");
      imai
    }
  }
}

Javaでも同じように書くためにBlockというinterfaceを導入してみた。

interface Block<A> { A body(); }

使い方:

class C {
  public C(Person p) {
    ...
  }

  public C() {
    this(new Block<Person>() {
      @Override public Person body() {
        Person imai = new Person("imai"); //デフォルトのPerson
        imai.setCurrentAddress("名古屋"); //現在の住所は"名古屋"
        return imai;
      }
    }.body());
  }
}

うーん...

2010-10-21 (Thu)

Scalaで戻り値の型でオーバーロードする

| 21:15 | Scalaで戻り値の型でオーバーロードする - yoshihiro503の関数的日記 を含むブックマーク はてなブックマーク - Scalaで戻り値の型でオーバーロードする - yoshihiro503の関数的日記

JavaScalaなどでオーバーロードする場合引数の数、または型が異なっていなければならない。例えば次のようなコードコンパイルエラーになる。

class C {
  def foo() : Int = 3
  def foo() : Long = 3L
  def foo() : String = "3"
}
Main.scala:4: error: method foo is defined twice
  def foo() : String = "3"
      ^
one error found

参考: Ideone.com - Online Compiler and IDE >> C/C++, Java, PHP, Python, Perl and 40+ other compilers and interpreters

こんなときJavaでは別名のメソッドにするしかないが、Scalaではimplicit parameterを使ってこれを実現できる。

class C {
  def foo[X](implicit f : X) : X = f

  private implicit def f1 : Int = 3
  private implicit def f2 : Long = 3L
  private implicit def f3 : String = "3"
}

参考: Ideone.com - Online Compiler and IDE >> C/C++, Java, PHP, Python, Perl and 40+ other compilers and interpreters

このクラス使用者はfooという名前でいろいろなところで使うことができるようになる。