scala中有没有办法明确要求隐式转换,或者 总是为此目的定义函数?
import collection.JavaConversions._
...
def toScalaCollections( v:Any ) : Any = {
v match {
case v2:java.lang.Map[Any] => v2.implicitly[ scala.collection.Map[Any] ]
case v2:java.lang.Iterable[Any] => v2.implicitly[ scala.collection.Iterable[Any] ]
...
}
}
语言中是否存在隐含的操作符?
NB。显然我可以通过定义
来解决import collection.JavaConversions._
...
def toScalaCollections( v:Any ) : Any = {
v match {
case v2:java.lang.Map[Any] => toScalaMap(v2)
case v2:java.lang.Iterable[Any] => toScalaList(v2)
...
}
}
我的观点是,是否有可能不必这样做?
答案 0 :(得分:10)
根本不要使用JavaConversions
。这正是为什么有时隐式转换很糟糕的例子。由于Scala集合框架非常复杂并且所有集合都具有多种方法,因此很难控制何时应进行隐式转换。 JavaConversions
确实应该被弃用 - 这是Scala社区中广泛接受的观点。
请改用JavaConverters
。此API提供了简洁的方法asScala
和asJava
,可在您需要时执行转换:
import scala.collection.JavaConverters._
val sm = Map[String, String]("a" -> "b", "c" -> "d")
val jm: java.util.Map[String, String] = sm.asJava
val sm2: Map[String, String] = jm.asScala
assert(sm == sm2)
答案 1 :(得分:2)
在某些时候,您必须以某种方式指定您需要这些集合属于Scala集合类型。由于您的函数返回类型Any
,Scala无法理解您的意图是返回Scala类型的集合。这是我所知道的最简洁的方法,可以实现您的目标:
import collection.JavaConversions._
def toScalaCollections( v:Any ) : Any = {
v match {
case v2:java.util.Map[Any, Any] => v2:scala.collection.mutable.Map[Any, Any]
case v2:java.lang.Iterable[Any] => v2:Iterable[Any]
}
}
请注意,我使用了Scala的可变映射,因为JavaConversions
不支持不可变映射。