我有一個應用程序在scala.collection.immutable.Map中使用連續查找,使用相同的鍵,這導致返回兩個不同的引用。喜歡的東西下面:Scala不可變映射爲同一個鍵返回不同的值
val v1 = m(key)
val v2 = m(key)
require(v1 eq v2) // fails!
我一直無法重現一個小例子這種行爲,我想知道是否有下,這可能是合理的/預期的任何情況。該應用程序是單線程的,我通過查找一個接一個地查找問題來隔離這個問題。
我有一個應用程序在scala.collection.immutable.Map中使用連續查找,使用相同的鍵,這導致返回兩個不同的引用。喜歡的東西下面:Scala不可變映射爲同一個鍵返回不同的值
val v1 = m(key)
val v2 = m(key)
require(v1 eq v2) // fails!
我一直無法重現一個小例子這種行爲,我想知道是否有下,這可能是合理的/預期的任何情況。該應用程序是單線程的,我通過查找一個接一個地查找問題來隔離這個問題。
我懷疑你正在測試參考平等。在這種情況下,v1和v2是不同的對象。除非您創建案例類,否則引用相等是類的默認值。
但v1和v2應該是同一個對象。如果他使用'get',那麼這將是一個不同的故事(不同的'選項'實例) –
Luigi - 我也希望返回的值是相同的。雖然這些值在'equals'下是等價的,但它們的引用(如'eq'測試的)不是。 – zoidbergsky
是否有可能您的地圖是不可變的,但您使用的鍵是可變的或有不正確的hashcode
和equals
實現返回非確定性結果?你使用的是什麼類型?
過分誇張的REPL例如:
scala> import scala.util.Random
import scala.util.Random
scala> class BadKey(val value: Int) {
| override def hashCode = Random.nextInt(Int.MaxValue)
|
| override def equals(x: Any) = Random.nextBoolean
| }
defined class BadKey
scala> val randMap = Map(new BadKey(1) -> 1, new BadKey(2) -> 2)
randMap: scala.collection.immutable.Map[BadKey,Int] = Map([email protected] -> 1, [email protected] -> 2)
scala> randMap.get(new BadKey(1))
res6: Option[Int] = Some(1)
scala> randMap.get(new BadKey(1))
res7: Option[Int] = Some(2)
scala> randMap.get(new BadKey(1))
res8: Option[Int] = Some(1)
scala> randMap.get(new BadKey(1))
res9: Option[Int] = Some(1)
scala> randMap.get(new BadKey(1))
res10: Option[Int] = Some(1)
scala> randMap.get(new BadKey(1))
res11: Option[Int] = None
這些鍵是可變的(包含'var'字段),但它們在兩個'apply'調用之間沒有變異。 'hashcode'和'equals'方法是確定性的,它們被實現爲僅僅依賴於對象的一個'val'字段,並且每個對象具有該字段的唯一值。 – zoidbergsky
你有併發?你有副作用'hashcode'或'equals'方法嗎? – ziggystar
該應用程序是順序的(沒有併發)。 'hashcode'是一個'Int' val'(每個對象都是唯一的),'equals'比較'hashcode'的值。 – zoidbergsky