编译以下代码失败,但是如果我删除方法点中的专用注释,它就会通过.
Scala代码运行器版本2.12.0-RC2 – 版权所有2002-2016,LAMP / EPFL和Lightbend,Inc.
abstract class Op[@specialized Left,@specialized Right] { @specialized type Result def r: Numeric[Result] def times(left: Left,right: Right): Result } object Op { implicit object IntDoubleOp extends Op[Int,Double] { type Result = Double val r = implicitly[Numeric[Double]] def times(left: Int,right: Double): Double = left * right } } object calc { def dot[@specialized Left,@specialized Right](xs: Array[Left],ys: Array[Right]) (implicit op: Op[Left,Right]): op.Result = { var total = op.r.zero var index = xs.length while(index > 0) { index -= 1 total = op.r.plus(total,op.times(xs(index),ys(index))) } total } }
test.scala:31: error: type mismatch; found : op.Result required: op.Result total ^ one error found
这是另一个没有运气的尝试:
//cat Ops.scala import scala.{ specialized => sp } trait OpsResult { type N } trait SymOps extends OpsResult { @sp override type N def zero: N def plus(left: N,right: N): N } trait AsyOps[@sp L,@sp R] extends OpsResult { @sp override type N def times(left: L,right: R): N } trait MixOps[@sp L,@sp R] extends AsyOps[L,R] with SymOps object MixOps { trait DoubleOps extends SymOps { override type N = Double def zero: Double = 0.0 override def plus(left: Double,right: Double): Double = left + right } trait IntDoubleOps extends AsyOps[Int,Double] { override type N = Double override def times(left: Int,right: Double): Double = left * right } implicit object MixIntDouble extends IntDoubleOps with DoubleOps } object Test { def dot[@sp L,@sp R](xs: Array[L],ys: Array[R]) (implicit op: MixOps[L,R]): op.N = { op.zero } }
$scalac Ops.scala Ops.scala:36: error: type mismatch; found : op.N required: op.N op.zero ^ one error found
解决方法
这是一个错误(也在2.11.x上重现).我已经联系过LightBend的人,这对于专业化和路径依赖类型的代码生成来说肯定是个怪癖.我把它缩小到一个苗条的重现:
trait M[@specialized T] { type Res def res: Res } object Test { def m[@specialized T](op: M[T]): op.Res = op.res }
op的符号将不同步,并且不会像您在代码中看到的那样进行编译. @AdriaanMoors has opened a bug关于这个问题.
Adriaan还向Aleksandar Prokopec指出了this blog post,它指出了@specilization代码生成中的一些怪癖.