scala:如何明确要求隐式转换?

时间:2013-10-04 00:19:40

标签: scala

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)
    ...
  } 
}

我的观点是,是否有可能不必这样做?

2 个答案:

答案 0 :(得分:10)

根本不要使用JavaConversions。这正是为什么有时隐式转换很糟糕的例子。由于Scala集合框架非常复杂并且所有集合都具有多种方法,因此很难控制何时应进行隐式转换。 JavaConversions确实应该被弃用 - 这是Scala社区中广泛接受的观点。

请改用JavaConverters。此API提供了简洁的方法asScalaasJava,可在您需要时执行转换:

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不支持不可变映射。