gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 15:47:46 24 4
gpt4 key购买 nike

根据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)

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

这是我所拥有的差异的一个例子:
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案例,而不是案例类文本提取器案例。
你知道警告的原因/我应该怎么做才能避免这个警告吗?

注:如果你想在 REPL 中测试它,最简单的方法是:
  • 激活未经检查的警告

    标度> :power

    Scala> settings.unchecked.value = true
  • 以粘贴模式复制上述代码:

    标度> :paste

    [复制粘贴]

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

    两种方法 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())))

    关于scala - 自制提取器和案例类提取器的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7008428/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com