scala - 从 Scala Set 到 Java Set 的隐式转换

标签 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!!!
    }

当我尝试编译此代码时出现错误:

"error: type mismatch;
   found   : scala.collection.immutable.Set[Moo]
   required: java.util.Set[Goo]
           var javaSet : util.Set[Goo] = ***Set(new Moo)***"

显式定义编译。为什么隐式转换不起作用?

最佳答案

这确实很棘手。基本上你的想法是正确的。您定义一个导入的转换方法 scalaSetToJavaSet。问题来自以下事实:(Scala 的) Set[A] 在其类型参数 A 中是不变的。这意味着 Set[Moo] 不是 Set[Bar[_]] 的子类型。

为了解决这个问题,您需要告诉隐式转换集合元素可以是 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

您现在可以这样理解:给定类型 D 和类型参数为 DBar 的某个子类型,执行转换。此方法现在称为 scalaSetToJavaSet[Goo, Moo](而不是 scalaSetToJavaSet[Goo, Bar[Goo]])。


正如其他人指出的那样,使用 JavaConversions 中的现成转换比编写自己的转换更容易。

关于scala - 从 Scala Set 到 Java Set 的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19093871/

相关文章:

Scala - 定义自己的中缀运算符

c++ - 有符号和无符号之间的比较。 static_cast 是唯一的解决方案吗?

c++ - 从类到字符串的隐式和显式转换

scala - Scala 在标准库中有模数吗?

scala - 将查询字符串转换为 Scala 中的映射

scala - 我怎样才能有一个可选的 Sbt 设置?

C# 隐式/显式类型转换

scala - 如何使用intellij运行多模块sbt的所有scalatest?

scala - 当混合具有冲突的抽象覆盖的多个特征时,我如何预测将选择哪个实现?

scala - 找不到参数排序的隐式值