首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >国产提取器与案例类提取器的区别

国产提取器与案例类提取器的区别
EN

Stack Overflow用户
提问于 2011-08-10 09:15:50
回答 1查看 543关注 0票数 6

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

代码语言:javascript
复制
def unapply[tps](x: c[tps]) =
  if (x eq null) scala.None
  else scala.Some(x.xs11, ..., x.xs1k)

出于实现的原因,我希望能够在非case类上模拟此提取器的行为。但是,我的实现不能复制相同的行为。

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

代码语言:javascript
复制
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
}

我有以下警告:

代码语言:javascript
复制
<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类文本牵引器情况下。你知不知道发出警告的原因/我应该做些什么来避免这个警告?

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

  1. 激活未经检查的警告

scala>:电源

scala> settings.unchecked.value =

  • 在粘贴模式下复制上述代码:

scala>:粘贴

复制/粘贴

编辑:,正如Antoras提到的,它应该是一个编译器错误,也许scala版本是有用的:Scala2.9.0.1(经过快速测试,Scala2.9.1RC2中仍然存在)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-10 12:07:51

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

代码语言:javascript
复制
...
    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)
    };
...

不适用的两种方法的方法签名是相同的。

此外,代码运行良好(由于相同的方法,这与预期的一样):

代码语言:javascript
复制
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())))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7008428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档