gpt4 book ai didi

具有可变默认值的 Scala Map 始终指向同一个对象

转载 作者:行者123 更新时间:2023-12-05 02:32:03 25 4
gpt4 key购买 nike

Scala 版本:3.1

我想创建一个 String -> Int 映射,每个键可以指向多个 Int。

因此我选择具有默认可变 Buffer[Int] 的 map 。

但似乎所有的键总是指向同一个Buffer[Int]

请注意,第一个 m("a") += 1 也很奇怪,它在 += 之后什么也不打印,但默认值已更改,因此它在下一个 println 中打印 两个 1

此外,我该如何解决 mutable.Map+=Buffer+ 覆盖的问题=。如果 key 不存在,我希望 map 插入一个新的 Buffer,然后调用 buffer+=

  import scala.collection.mutable
val m: mutable.Map[String, mutable.Buffer[Int]] =
mutable.HashMap.empty.withDefaultValue(mutable.Buffer.empty)

m("a") += 1
println(m) // Map()

m("a") = m("a") += 1

println(m) // Map(a -> ArrayBuffer(1, 1))

m("b") = m("b") += 2 // Map(a -> ArrayBuffer(1, 1, 2), b -> ArrayBuffer(1, 1, 2)) , not expecting this, key is correct but

println(m) // Map(a -> ArrayBuffer(1, 1, 2), b -> ArrayBuffer(1, 1, 2))

m("a") = m("a") += 2

println(m) // Map(a -> ArrayBuffer(1, 1, 2, 2), b -> ArrayBuffer(1, 1, 2, 2)) ,
// this is not as I expected. The keys are correct, however their values are all the same ArrayBuffer

最佳答案

TL;DR:withDefaultValue 在这里没用。

注意 signature of withDefaultValue是:

def withDefaultValue(d: V): Map[K, V]

参数d取值,不是by name (=> V),因此它只计算一次。因此,原始映射中不存在的任何键都将返回您创建一次的相同空缓冲区。

您得到的 withDefaultValue(和 withDefault)是一个新的类 map 对象,而不是原始 map 。只有分配结果 (m("a") = ...) 才会改变它。

Note: The default is only used for apply. Other methods like get, contains, iterator, keys, etc. are not affected by withDefaultValue.

考虑这个例子:

val m = new HashMap[Integer, Buffer[String]]()
val mm = m.withDefault(_ => Buffer.empty)
mm(1).append("4")
mm(1) // ArrayBuffer()

您可能想要的是 getOrElseUpdate (如果你愿意,你可以定义一个辅助函数)带有签名

getOrElseUpdate(key: K, defaultValue: => V): V

注意这次 defaultValue 是如何按名称调用的,每次调用都会创建一个新的缓冲区:

val m: mutable.Map[String, mutable.Buffer[Int]] =
mutable.HashMap.empty

def mm(key: String): mutable.Buffer[Int] = m.getOrElseUpdate(key, mutable.Buffer.empty)

mm("a") += 1
mm("b") += 2
// now buffers at `a` and `b` are distinct

关于具有可变默认值的 Scala Map 始终指向同一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71376969/

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