0

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

语言中是否有隐含的运算符?

注意。显然我可以通过定义来解决

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

我的意思是,是否有可能不必这样做?

4

2 回答 2

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)
于 2013-10-04T05:50:45.377 回答
2

在某些时候,您必须以某种方式指定您需要这些集合是 Scala 集合类型。由于您的函数返回 type 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.

于 2013-10-04T02:23:27.527 回答