net*_*tta 2 scala implicit-conversion
我有以下内容:
class Goo
trait Bar[D] {
def toD : D
}
class Moo extends Bar[Goo] {
def toD : Goo = new Goo
}
object Foo {
import scala.collection.JavaConversions._
import java.util
implicit def scalaSetToJavaSet[D](bars: Set[Bar[D]]) : util.Set[D] = bars.map(_.toD)
}
trait Zoo {
import java.util
import Foo._
var javaSet : util.Set[Goo] = Set(new Moo) //compile error
var explicitJavaSet: util.Set[Goo] = scalaSetToJavaSet(Set(new Moo)) //works!!!
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译此代码时,我收到一个错误:
"error: type mismatch;
found : scala.collection.immutable.Set[Moo]
required: java.util.Set[Goo]
var javaSet : util.Set[Goo] = ***Set(new Moo)***"
Run Code Online (Sandbox Code Playgroud)
显式定义编译.为什么隐式转换不起作用?
这确实很棘手.基本上你的想法是正确的.您可以定义scalaSetToJavaSet导入的转换方法.问题来自于(Scala's)Set[A]在其类型参数中不变的事实A.这意味着它Set[Moo]不是一个子类型Set[Bar[_]].
为了解决这个问题,你需要告诉隐式转换,set元素可以是bar的子类型:
implicit def scalaSetToJavaSet[D, B <: Bar[D]](bars: Set[B]): java.util.Set[D] =
bars.map(_.toD)
val javaSet: java.util.Set[Goo] = scala.Set(new Moo) // ok
Run Code Online (Sandbox Code Playgroud)
您现在可以这样理解:给定类型D和Bar类型参数的某个子类型D,进行转换.此方法现在称为scalaSetToJavaSet[Goo, Moo](而不是scalaSetToJavaSet[Goo, Bar[Goo]]).
正如其他人所指出的那样,使用现成的转换更容易,JavaConversions而不是自己编写.
| 归档时间: |
|
| 查看次数: |
274 次 |
| 最近记录: |