gpt4 book ai didi

scala Map.getOrElse - 如何提供默认功能

转载 作者:行者123 更新时间:2023-12-04 10:04:13 26 4
gpt4 key购买 nike

奇怪的...

    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 的无参数函数。
  • 为什么采用 mydefault1 的示例会编译,因为它需要一个参数,因此符合规范?
  • 为什么返回函数,而不是调用函数来产生默认值?显然类型安全已被破坏,因为 getOrElse 必须返回一个 Int,而不是一个函数。 (如果我误解了文档并错误地提供了一个需要 Int 值的函数,为什么编译器让我提供一个函数而不是一个 Int?)。

  • 编辑

    清楚地:
  • 扩展 HashMap 并覆盖默认值,或
  • 使用 HashMap.withDefault

  • 也让一个函数用来指定一个默认值。我想要的是能够使用在执行查找时提供的函数覆盖默认值(即,该函数可能会在 map 的生命周期内发生变化)

    这可能吗?

    最佳答案

    The definition of getOrElse :

    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它必须是映射值类型 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!!

    关于scala Map.getOrElse - 如何提供默认功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20751197/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com