首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scala Map.getOrElse -如何提供默认函数

问scala Map.getOrElse -如何提供默认函数
EN

Stack Overflow用户
提问于 2013-12-23 21:07:51
回答 1查看 9.2K关注 0票数 7

奇怪..。

代码语言:javascript
复制
    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>

文档说默认值必须是类型:=> B

如果我正确理解,则返回Int的no-arg函数,在本例中。

  1. 为什么以mydefault1为例进行编译,因为它需要一个参数,因此符合规范?
  2. 为什么返回函数,而不是调用函数来生成默认值?显然,类型安全性已经中断,因为getOrElse必须返回Int,而不是函数。(如果我误解了文档,并且错误地提供了一个需要Int值的函数,为什么编译器允许我提供函数而不是Int?)

编辑

显然:

  • 扩展HashMap并重写默认值,或
  • 使用HashMap.withDefault

还可以使用函数指定默认值。我想要的是能够用在执行查找时提供的函数覆盖默认值(也就是说,函数在Map的生命周期中可能会发生变化)。

这个是可能的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-23 21:21:08

getOrElse

代码语言:javascript
复制
getOrElse[B1 >: B](key: A, default: => B1): B1

default参数不接受一个函数--它将是() => B1,而是一个延迟访问的B1类型的值。这种无参数的“函数”=> B1有时也称为thunk。正确的使用方法如下:

代码语言:javascript
复制
import collection.mutable

val h = new mutable.HashMap[Long, Int]()

def mydefault0(): Int = 101

println(h.getOrElse(99, default = mydefault0()))

那么你在mydefault0 _上看到的是什么呢?显然,返回的值有B1类型,它必须是映射值类型Int和默认值类型的公共超类型。默认值的类型是Function0。如果分配结果,则会看到超类为Any。

代码语言:javascript
复制
val x = h.getOrElse(99, default = mydefault0 _ )  // x: Any = <function0>

因此,错误是假设您必须传递一个函数,而实际上您是在声明一个被延迟计算的表达式。只有在需要默认值时才会调用调用mydefault0()。在形式上,参数被定义为点名参数。

编辑:关于你的评论。按名调用意味着每次都会得到一个新的数组。

代码语言:javascript
复制
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!!
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20751197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档