加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

这是scala的专业错误吗?

发布时间:2020-12-16 18:17:38 所属栏目:安全 来源:网络整理
导读:编译以下代码失败,但是如果我删除方法点中的专用注释,它就会通过. Scala代码运行器版本2.12.0-RC2 – 版权所有2002-2016,LAMP / EPFL和Lightbend,Inc. abstract class Op[@specialized Left,@specialized Right] { @specialized type Result def r: Numeric[
编译以下代码失败,但是如果我删除方法点中的专用注释,它就会通过.

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代码生成中的一些怪癖.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读