自制提取器和案例类提取器的区别

编程入门 行业动态 更新时间:2024-10-27 16:37:53
本文介绍了自制提取器和案例类提取器的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

根据scala规范,case类构建的提取器如下(scala规范§5.3.2):

According to the scala specification, the extractor built by case classes is the following (scala specification §5.3.2):

def unapply[tps](x: c[tps]) = if (x eq null) scala.None else scala.Some(x.xs11, ..., x.xs1k)

出于实现原因,我希望能够在非大小写类上模拟此提取器的行为.但是,我的实现无法重现相同的行为.

For implementation reasons, I want to be able to mimic the behavior of this extractor on a non-case class. However, my implementation fails to reproduce the same behavior.

这是我所拥有的差异的一个例子:

Here is an example of the difference i have:

trait A sealed trait B[X <: A]{ val x: X } case class C[X <: A](x: X) extends B[X] class D[X <: A](val x: X) extends B[X] object D { def unapply[X <: A](d: D[X]): Option[X] = if (d eq None) None else Some(d.x) } def ext[X <: A](b: B[X]) = b match { case C(x) => Some(x) case D(x) => Some(x) case _ => None }

我有以下警告:

<console>:37: warning: non variable type-argument X in type pattern D[X] is unchecked since it is eliminated by erasure case D(x) => Some(x)

注意警告只发生在 D 的情况下,而不是在 case-class texttractor 的情况下.你知道警告的原因/我应该怎么做才能避免这个警告吗?

Notice the warning occurs only in the D case, not in the case-class textractor case. Do you have any idea about the cause of the warning / about what I should do to avoid this warning ?

注意:如果你想在 REPL 中测试它,最简单的方法是:

Note: If you want to test it in REPL, the easiest way is:

  • 激活未选中的警告

  • To activate unchecked warning

    scala> :power

    scala> :power

    scala> settings.unchecked.value = true

    scala> settings.unchecked.value = true

    以粘贴模式复制以上代码:

    To copy above code in paste mode:

    scala> :paste

    scala> :paste

    [复制/粘贴]

    [ctrl + D]

    正如 Antoras 提到的,它应该是一个编译器错误,也许 scala 版本可能有用:scala 2.9.0.1(经过快速测试,仍然存在于 Scala 2.9.1RC2 中)

    As Antoras mentioned it should be a compiler bug, maybe the scala version could be useful: scala 2.9.0.1 (after a quick test, still there in scala 2.9.1RC2)

    推荐答案

    这似乎是一个编译器错误.我已经分析了编译器 AST 的输出(使用 fsc -Xprint:typer .scala).它将两者解释为相同:

    This seems to be a compiler bug. I have analyzed the output of the compiler AST (with fsc -Xprint:typer <name_of_file>.scala). It interprets both as the same:

    ... final <synthetic> object C extends java.lang.Object with ScalaObject with Serializable { def this(): object test.Test.C = { C.super.this(); () }; final override def toString(): java.lang.String = "C"; case <synthetic> def unapply[X >: Nothing <: test.Test.A](x$0: test.Test.C[X]): Option[X] = if (x$0.==(null)) scala.this.None else scala.Some.apply[X](x$0.x); case <synthetic> def apply[X >: Nothing <: test.Test.A](x: X): test.Test.C[X] = new test.Test.C[X](x); protected def readResolve(): java.lang.Object = Test.this.C }; ... final object D extends java.lang.Object with ScalaObject { def this(): object test.Test.D = { D.super.this(); () }; def unapply[X >: Nothing <: test.Test.A](d: test.Test.D[X]): Option[X] = if (d.eq(null)) scala.None else scala.Some.apply[X](d.x) }; ...

    两个方法 unapply 的方法签名是相同的.

    The method signature of both methods unapply are identical.

    此外,代码工作正常(由于相同的方法,正如预期的那样):

    Furthermore the code works fine (as expected due to identical methods):

    trait A { def m = "hello" } class AA extends A sealed trait B[X <: A]{ val x: X } case class C[X <: A](x: X) extends B[X] class D[X <: A](val x: X) extends B[X] object D { def apply[X <: A](x: X) = new D(x) def unapply[X <: A](d: D[X]): Option[X] = if (d eq null) None else Some(d.x) } def ext[X <: A](b: B[X]) = b match { case C(x) => Some("c:"+x.m) case D(x) => Some("d:"+x.m) case _ => None } println(ext(C[AA](new AA()))) println(ext(D[AA](new AA())))
  • 更多推荐

    自制提取器和案例类提取器的区别

    本文发布于:2023-11-25 07:37:23,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1628888.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:区别   案例

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!