Scala:从泛型到第二泛型的隐式转换

标签 scala generics type-conversion implicit

假设我有两组类,第一组继承自 Foo,第二组继承自 Bar。

class Foo
class Baz extends Foo
class Bar
class Qux extends Bar

我想创建一个通用的隐式转换函数,将任何 Foo 转换为 Bar 给定范围内有一个隐式转换器类型。
trait Converter[A <: Foo, B <: Bar] {
  def convert(a : A) : B
}

implicit object BazToQuxConverter extends Converter[Baz, Qux] {
  def convert(a : Baz) : Qux = new Qux
}

implicit def FooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, B]) : B = converter.convert(a)

不幸的是,这似乎不像我期望的那样工作。当我将以下几行插入 REPL 时:
val a : Baz = new Baz
val b : Qux = a

...我收到以下错误:
<console>:17: error: type mismatch;
 found   : Baz
 required: Qux
       val b : Qux = a
                     ^

有什么办法可以让它发挥作用吗?我最接近的是以下内容:
implicit def BadFooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, _]) : B = converter.convert(a).asInstanceOf[B]

这确实适用于我之前的示例,但它不是非常类型安全。
class Qax extends Bar
val a : Baz = new Baz
val b : Qax = a

这将编译得很好,但它会在运行时爆炸,因为 Qux ( converter.convert(a) 的结果)不能转换为 Qax ( asInstanceOf[Qax] )。理想情况下,我希望它能够在编译时捕获上述行,因为没有任何 Converter[Bax,Qax]在适用范围。

最佳答案

这是一个在 2.11 中修复的错误。看起来它已经从 PR 2822 开始修复了, 相关工单是 SI-3346 .

Welcome to Scala version 2.11.0-20131030-090728-c38235fd44 (OpenJDK 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

  class Foo
  class Baz extends Foo
  class Bar
  class Qux extends Bar

  trait Converter[A <: Foo, B <: Bar] {
    def convert(a : A) : B
  }

  implicit object BazToQuxConverter extends Converter[Baz, Qux] {
    def convert(a : Baz) : Qux = new Qux
  }

  import scala.language.implicitConversions
  implicit def FooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, B]) : B = converter.convert(a)

  val a : Baz = new Baz
  val b : Qux = a

// Exiting paste mode, now interpreting.

defined class Foo
defined class Baz
defined class Bar
defined class Qux
defined trait Converter
defined object BazToQuxConverter
import scala.language.implicitConversions
FooToBar: [A <: Foo, B <: Bar](a: A)(implicit converter: Converter[A,B])B
a: Baz = Baz@4f4db2ac
b: Qux = Qux@760d62e0

关于Scala:从泛型到第二泛型的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19776508/

相关文章:

java - 为什么在这种情况下删除通用类型会阻止覆盖?

c++ - 模板类中的模板转换运算符-函数指针

java - 转换或方法调用哪个更有效/更便宜?

scala - 在 Scala 3 中是否可以通过泛型类型进行模式匹配?

generics - Kotlin将类转换为Unit

c# - 如何在 C# 中进行静态转换?

Scala:在for循环中声明val,如果条件

scala - 可以使用 reduceBykey 来更改类型和组合值 - Scala Spark?

scala - 无法解析 org.scalatest#scalatest;3.0.1 : not found dependency issue

scala - 在 SBT 中测试初始命令