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

Posted

技术标签:

【中文标题】Scala:从泛型类型到第二泛型类型的隐式转换【英文标题】:Scala: Implicit Conversion From Generic Type to Second Generic Type 【发布时间】:2013-11-15 14:09:59 【问题描述】:

假设我有两组类,第一组继承自 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

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

【问题讨论】:

你能看一下吗:***.com/questions/19335385/… 这看起来很相似 该线程似乎是关于将转换链接在一起,我的问题只是关于两个泛型类型之间的隐式转换。不确定该线程中的任何内容如何适用于我的问题。 【参考方案1】:

这是一个在 2.11 中修复的错误。从PR 2822开始好像已经修复了,相关的ticket是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 错误,但很高兴知道它已修复。我想知道 2.10 中是否有解决方法...

以上是关于Scala:从泛型类型到第二泛型类型的隐式转换的主要内容,如果未能解决你的问题,请参考以下文章

泛型类型的隐式转换?

Scala 宏介绍

25.scala的隐式转换

不可不会的scala隐式转换

Scala语法基础之隐式转换

Scala中的隐式转换|理解