我有一个测试,当我迭代Map
中的值时因为排序问题而间歇性地失败。
Scala有助于提供ListMap
,这会使测试稳定,但会牺牲性能。所以我将ImmutableMapFactory
抽象为val并在我的代码中使用它。
class C {
val immutableMapFactory = scala.collection.immutable.Map
def func = {
...
immutableMapFactory(pairs :_*)
}
}
现在我的计划是扩展C并覆盖immutableMapFactory
以进行测试
class TestableC extends C {
override val immutableMapFactory = scala.collection.immutable.ListMap
}
不足为奇,因为ListMap
与Map
的类型不同,所以失败了。我应该如何指定val(或def)的类型,以便我可以在任何需要的地方使用工厂来创建Map?
答案 0 :(得分:3)
两种可能的方式。首先,使用def
和函数,我认为这是一个更好的抽象。
class C {
def immutableMapFactory[A,B]: ((A,B)*) => Map[A,B] = scala.collection.immutable.Map.apply _
}
class TestableC extends C {
override def immutableMapFactory[A,B] = scala.collection.immutable.ListMap.apply _
}
其次,使用val
和结构类型:
class C {
val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.Map
}
class TestableC extends C {
override val immutableMapFactory: { def apply[A,B](t: (A,B)*): Map[A,B] } = scala.collection.immutable.ListMap
}
答案 1 :(得分:2)
你的问题在这一行:
val immutableMapFactory = scala.collection.immutable.Map
这使immutableMapFactory
等于单例对象Map
。 ListMap
(单例)不是Map
(单例)的子类,因此后续覆盖失败。
如果您改为从apply
获取Map
方法,并将其部分应用于形成第一类函数(类型为(A, B)* => immutable.Map[A,B]
),则可以使该技术起作用:< / p>
import collection.immutable
class Bip {
def fac[A,B] = immutable.Map.apply[A,B] _
}
class Bop extends Bip {
override def fac[A,B] = immutable.ListMap.apply[A,B] _
}