奇怪的...
val h = new HashMap[Long, Int]()
def mydefault0():Int = 101
println( h.getOrElse(99, default=mydefault0 _ ) ) // Prints <function0>
def mydefault1(key:Long):Int = 102
println( h.getOrElse(98, default=mydefault1 _ ) ) // Prints <function1>
docs 说默认必须是类型:=> B
如果我理解正确,在这种情况下,一个无参数函数返回一个 Int。
编辑
清楚地:
还让一个函数用于指定一个默认值。我想要的是能够使用在执行查找时提供的函数来覆盖默认值(即该函数可能会在 Map 的生命周期中发生变化)
这可能吗?
最佳答案
getOrElse[B1 >: B](key: A, default: => B1): B1
default
参数不带函数-可能是() => B1
,但是是类型为B1
的延迟访问值。这种无参数的“函数” => B1
有时也称为thunk。正确的使用方法如下:import collection.mutable
val h = new mutable.HashMap[Long, Int]()
def mydefault0(): Int = 101
println(h.getOrElse(99, default = mydefault0()))
那么,您看到的
mydefault0 _
是什么?显然,返回值的类型为B1
,它必须是 map 的值类型Int
和默认值的类型的通用父类(super class)型。默认值的类型是Function0
。如果分配结果,则会看到父类(super class)型为Any
:val x = h.getOrElse(99, default = mydefault0 _ ) // x: Any = <function0>
因此,错误是假设您实际上在陈述一个被延迟计算的表达式时,必须传递一个函数。仅当需要默认值时,才会调用
mydefault0()
调用。形式上,自变量定义为call-by-name自变量。编辑:关于您的评论。按名称调用意味着您每次都会得到一个新数组。
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!!