scala – 自制提取器和案例类提取器之间的区别

前端之家收集整理的这篇文章主要介绍了scala – 自制提取器和案例类提取器之间的区别前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
根据 scala规范,由case类构建的提取器如下(scala规范§5.3.2):

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

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

以下是我的差异示例:

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 textractor情况下发生.
您是否知道警告的原因/我应该怎么做才能避免这种警告?

注意:如果要在REPL中进行测试,最简单的方法是:

>激活未经检查的警告

阶> :功率

阶> settings.unchecked.value = true
>要在粘贴模式下复制上面的代码

阶> :糊

[复制粘贴]

[ctrl D]

编辑:正如Antoras所说,它应该是编译器错误,也许scala版本可能有用:scala 2.9.0.1
(经过快速测试后,仍然在scala 2.9.1RC2中)

解决方法

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

...
    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)
    };
...

两种方法方法签名都不相同.

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

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())))
原文链接:https://www.f2er.com/scala/827923.html

猜你在找的Scala相关文章