根据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
情况,而不是情况类 texttractor 情况。
您是否知道警告的原因/我应该做什么来避免此警告?
Note:如果你想在 REPL 中测试它,最简单的方法是:
-
激活未检查的警告
标量>:功率
scala> settings.unchecked.value = true
-
要以粘贴模式复制以上代码:
斯卡拉>:粘贴
[复制粘贴]
[Ctrl+D]
Edit:正如 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)
};
...
两种方法 unapply 的方法签名是相同的。
此外,代码运行良好(正如预期的那样,由于方法相同):
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())))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)