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

scala – 它是一个类型检查错误吗?

发布时间:2020-12-16 18:08:23 所属栏目:安全 来源:网络整理
导读:我把它缩小到下面的代码: trait A[T] { def apply(t: T): Int}sealed trait P { def apply(): Int}case class I[T](a: A[T],t: T) extends P { def apply: Int = a(t)}case class X[T1,T2](a1: A[T1],a2: A[T2]) extends A[(T1,T2)] { def apply(t: (T1,T2)
我把它缩小到下面的代码:

trait A[T] {
  def apply(t: T): Int
}

sealed trait P {
  def apply(): Int
}

case class I[T](a: A[T],t: T) extends P {
  def apply: Int = a(t)
}

case class X[T1,T2](a1: A[T1],a2: A[T2]) extends A[(T1,T2)] {
  def apply(t: (T1,T2)): Int =
    t match {
      case (t1,t2) => a1(t1) + a2(t2)
    }
}

object m {
  def apply(p1: P,p2: P): P =
    (p1,p2) match {
      case (I(a1,t1),I(a2,t2)) =>
        I(X(a1,a2),(t2,t1)) // <-- Here
    }
}

如您所见,我在标有< - Here的行中有一个类型错误.然而,代码编译时甚至没有警告,并且在运行时因ClassCastException而失败.代码:

case class E() extends A[Int] {
  def apply(t: Int): Int = t
}

case class S() extends A[String] {
  def apply(t: String): Int = t.length
}

object Test {
  def apply() = {
    val pe: P = I(E(),3)
    val ps: P = I(S(),"abcd")
    val pp: P = m(pe,ps)
    pp()
  }
}

我知道当模式匹配scala有时无法检查值是否为正确类型时,但这通常会导致编译器警告.

那么,这是一个错误,还是我想念一些东西?

更新:我担心的是我可以犯一个类型错误,编译器甚至不会警告我.我明白(t1,t2)是正确的顺序;但如果我写得不正确,我会在执行程序之前发现它,甚至可能更晚,尽管它显然是一个类型错误.

解决方法

也许缺乏警告与此有关:

https://issues.scala-lang.org/browse/SI-9188

它似乎没有对A上的类型参数做任何有用的事情,除非它可以静态地证明你弄错了.

这里的最后一场比赛应警告:

scala> val i = I(E(),42)
i: I[Int] = I(E(),42)

scala> i match { case I(a: A[Int],x) => }

scala> i match { case I(a: A[String],x) => }
<console>:15: warning: non-variable type argument String in type pattern A[String] is unchecked since it is eliminated by erasure
              i match { case I(a: A[String],x) => }
                                  ^
<console>:15: error: pattern type is incompatible with expected type;
 found   : A[String]
 required: A[Int]
              i match { case I(a: A[String],x) => }
                                  ^

scala> (i: P) match { case I(a: A[String],x) => }
<console>:15: warning: non-variable type argument String in type pattern A[String] is unchecked since it is eliminated by erasure
              (i: P) match { case I(a: A[String],x) => }
                                       ^
<console>:15: error: pattern type is incompatible with expected type;
 found   : A[String]
 required: A[Any]
Note: String <: Any,but trait A is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
              (i: P) match { case I(a: A[String],x) => }
                                       ^

scala> (i: P) match { case I(a: A[Int],x) => }
<console>:15: warning: non-variable type argument Int in type pattern A[Int] is unchecked since it is eliminated by erasure
              (i: P) match { case I(a: A[Int],x) => }
                                       ^
<console>:15: error: pattern type is incompatible with expected type;
 found   : A[Int]
 required: A[Any]
Note: Int <: Any,but trait A is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
              (i: P) match { case I(a: A[Int],x) => }
                                       ^

scala> (i: P) match { case I(a: A[_],x) => }

scala> (i: P) match { case I(a: A[Any],x) => }

只是添加:

scala> (i: P) match { case I(a: A[Any],x) => a("foo") }
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
  at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:105)
  at E.apply(<console>:33)
  ... 33 elided

(编辑:李大同)

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

    推荐文章
      热点阅读