相信我; 您不 希望
来回透明转换。这正是这些
scala.collection.jcl.Conversions功能试图执行的操作。在实践中,这会引起很多头痛。
这种方法的问题根源在于,Scala会根据需要自动注入隐式转换,以使方法调用起作用。这可能会带来一些非常不幸的后果。例如:
import scala.collection.jcl.Conversions._// adds a key/value pair and returns the new map (not!)def process(map: Map[String, Int]) = { map.put("one", 1) map}对于Scala集合框架的新手,甚至不可变集合的概念,此代码不会完全不合时宜。不幸的是,这是完全错误的。此函数的结果是 同
一张图。对的调用会
put触发对的隐式转换
java.util.Map<String,Int>,该转换很乐意接受新值并被立即丢弃。原始文件
map未经修改(实际上是不可变的)。
豪尔赫·奥尔蒂斯(Jorge Ortiz)最好地指出,您仅应出于以下两个目的之一来定义隐式转换:
- 添加成员(方法,字段等)。这些转换应为 与 范围内其他任何内容均 无关 的新类型。
- “修复”破碎的类层次结构。因此,如果您有某些类型,
A
并且B
这些类型无关。您可以定义一个转换,A => B
当且 仅 当您希望拥有A <: B
(<:
表示“子类型”)时。
由于
java.util.Map显然不是与我们层次结构中的任何事物都无关的新类型,因此我们不能属于第一个附带条件。因此,我们唯一的希望是我们的转换
Map[A,B] => java.util.Map[A, B]有资格获得第二个。但是,Scala
Map继承自绝对没有任何意义
java.util.Map。它们实际上是完全正交的接口/特征。如上所述,尝试忽略这些准则几乎总是会导致奇怪和意外的行为。
事实是javautils
asScala和
asJava方法旨在解决这个确切的问题。从中的javautils中有一个隐式转换(实际上有许多转换)
Map[A, B] =>RichMap[A, B]。
RichMap是javautils定义的全新类型,因此它的唯一目的是向中添加成员
Map。特别是,它添加了
asJava方法,该方法返回一个包装器映射,该包装器实现
java.util.Map并委托给您的原始
Map实例。这使过程更加明确,并且出错的可能性也大大降低。
换句话说,使用
asScala和
asJava是
最佳做法。在生产应用程序中独立走过这两条路之后,我可以直接告诉您javautils方法更安全,更容易使用。不要仅仅为了节省自己的8个字符而试图规避其保护!



