Lam*_*ght 10 generics scala implicit type-conversion
假设我有两组类,第一组继承自Foo,第二组继承自Bar.
class Foo
class Baz extends Foo
class Bar
class Qux extends Bar
Run Code Online (Sandbox Code Playgroud)
我想创建一个通用的隐式转换函数,将任何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)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这似乎不像我期望的那样有效.当我将以下行插入REPL时:
val a : Baz = new Baz
val b : Qux = a
Run Code Online (Sandbox Code Playgroud)
...我收到以下错误:
<console>:17: error: type mismatch;
found : Baz
required: Qux
val b : Qux = a
^
Run Code Online (Sandbox Code Playgroud)
有没有办法让这个工作?我能够得到的最接近的是:
implicit def BadFooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, _]) : B = converter.convert(a).asInstanceOf[B]
Run Code Online (Sandbox Code Playgroud)
这适用于我之前的示例,但它不是非常类型安全的.
class Qax extends Bar
val a : Baz = new Baz
val b : Qax = a
Run Code Online (Sandbox Code Playgroud)
这将编译得很好,但它会在运行时爆炸,因为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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1434 次 |
| 最近记录: |