getOrElse definition :
getOrElse[B1 >: B](key: A, default: => B1): B1
The default argument does not accept a function that would be () => B1 , but a lazily accessible value of type B1 . This parameterless "function" => B1 also sometimes called thunk. The correct way to use:
import collection.mutable val h = new mutable.HashMap[Long, Int]() def mydefault0(): Int = 101 println(h.getOrElse(99, default = mydefault0()))
So what do you see with mydefault0 _ ? Obviously, the return value is of type B1 , which should be a common supertype of the type of the value of the map Int and the type of the default. The default value type is Function0 . If you assign a result, you will see that the supertype Any :
val x = h.getOrElse(99, default = mydefault0 _ )
So the mistake is to suggest that you should pass a function when you are actually specifying an expression that is lazily evaluated. A call to mydefault0() will only be called if necessary by default. Formally, an argument is defined as a call-by-name argument.
Change Regarding your comment. Call-by-name means that you get a new array every time.
val m = Map("foo" -> Array(1, 2, 3)) def myDefault = { println("called-default") Array(4, 5, 6) } val a1 = m.getOrElse("foo", myDefault) // myDefault not called val a2 = m.getOrElse("bar", myDefault) // myDefault called val a3 = m.getOrElse("baz", myDefault) // myDefault called a2 == a3 // false!!
source share