ヤパーリ

skalabe2011-03-10

Javaだと以下のコードはコンパイれる。

	public String method(List<String> list, Integer arg1) {
		return "Hello";
	}

	public String method(Integer arg1, List<String> list) {
		return "World";
	}

scalaだと以下のコードはコンパイれないもしくは
後勝ちになるぅ。

scala> def method(list : List[String], arg1 : Int) : String = {return "Hello"}
method: (list: List[String],arg1: Int)String

scala> def method(arg1 : Int, list : List[String]) : String = {return "World"}
method: (arg1: Int,list: List[String])String

scala> method(List(""), 1)
<console>:7: error: type mismatch;
 found   : List[java.lang.String]
 required: Int
       method(List(""), 1)
                  ^

scala> method(1, List(""))
res1: String = World

scala> def method(list : List[String], arg1 : Int) : String = {return "Hello"}
method: (list: List[String],arg1: Int)String

scala> method(1, List(""))
<console>:7: error: type mismatch;
 found   : Int(1)
 required: List[String]
       method(1, List(""))
              ^

scala> method(List(""), 1)
res3: String = Hello

まぁそんなに実害ないけど、むしろデフォルト引数や
名前付き引数が使えるメリットの方が大きい。
ではってことで、片方のメソッドがデフォルト引数を持っていたら?

scala> def method(list : List[String], arg1 : Int, arg2 : String = "Hello,Hello") : String = {return arg2}
method: (list: List[String],arg1: Int,arg2: String)String

scala> method(List(""), 10)
res5: String = Hello,Hello

scala> def method(arg1 : Int, list : List[String]) : String = {return "World"}
method: (arg1: Int,list: List[String])String

scala> method(List(""), 10)
<console>:7: error: type mismatch;
 found   : List[java.lang.String]
 required: Int
       method(List(""), 10)
                  ^

scala> method(1, List(""))
res7: String = World
scala>

今度は、明らかにシグニチャが異なる(引数が3つと2つ)のに
後勝ちになる。
もう一歩踏み込んで、あえてデフォルト引数の部分に明示的にnullを入れてみると

scala> def method(list : List[String], arg1 : Int, arg2 : String = "Hello,Hello") : String = {return arg2}
method: (list: List[String],arg1: Int,arg2: String)String

scala> method(List(""), 100, null)
res8: String = null

nullかよ!
デフォルト引数が補完されるのかと思ってた。
てことは結局、同じような機能で同じような引数のメソッドがある場合、
デフォルト引数で、オーバーロードの削減が出来るけど、
値がnullがどうかは、メソッド側でやらんといけないのね。。。
んじゃ、Someでラップすればnullポインターは出ない?

scala> def method(list : List[String], arg1 : Int, arg2 : Some[String] = Some("Hello,Hello")) : Some[String] = {return arg2}
method: (list: List[String],arg1: Int,arg2: Some[String])Some[String]

なーんか冗長感が否めない。
ここらへんは、実際に使う時に何か考えないとなぁ。