gpt4 book ai didi

Scala:案例类不适用与手动实现和类型删除

转载 作者:行者123 更新时间:2023-12-01 05:47:45 25 4
gpt4 key购买 nike

我试图了解 Scala 对案例类做了什么,这使得它们在某种程度上不受类型删除警告的影响。
假设我们有以下简单的类结构。它基本上是 Either :

abstract class BlackOrWhite[A, B]

case class Black[A,B]( val left: A ) extends BlackOrWhite[A,B]

case class White[A,B]( val right: B ) extends BlackOrWhite[A,B]
你正试图像这样使用它:
object Main extends App {

def echo[A,B] ( input: BlackOrWhite[A,B] ) = input match {
case Black(left) => println( "Black: " + left )
case White(right) => println( "White: " + right )
}

echo( Black[String, Int]( "String!" ) )
echo( White[String, Int]( 1234 ) )
}
一切都编译并运行没有任何问题。但是,当我尝试实现 unapply我自己的方法,编译器会抛出一个警告。我使用了以下具有相同 Main 的类结构上面的类:
abstract class BlackOrWhite[A, B]

case class Black[A,B]( val left: A ) extends BlackOrWhite[A,B]

object White {

def apply[A,B]( right: B ): White[A,B] = new White[A,B](right)

def unapply[B]( value: White[_,B] ): Option[B] = Some( value.right )

}

class White[A,B]( val right: B ) extends BlackOrWhite[A,B]
-unchecked 编译它flag 发出以下警告:
[info] Compiling 1 Scala source to target/scala-2.9.1.final/classes...
[warn] src/main/scala/Test.scala:41: non variable type-argument B in type pattern main.scala.White[_, B] is unchecked since it is eliminated by erasure
[warn] case White(right) => println( "White: " + right )
[warn] ^
[warn] one warning found
[info] Running main.scala.Main
现在,我了解类型删除,并且我尝试使用 Manifests 绕过警告。 (到目前为止无济于事),但是这两种实现有什么区别?案例类是否在做一些我需要添加的事情?可以用 Manifests 规避吗? ?
我什至尝试使用 -Xprint:typer 通过 scala 编译器运行案例类实现。标志打开,但 unapply方法看起来很像我预期的:
case <synthetic> def unapply[A >: Nothing <: Any, B >: Nothing <: Any](x$0: $iw.$iw.White[A,B]): Option[B] = if (x$0.==(null))
scala.this.None
else
scala.Some.apply[B](x$0.right);

最佳答案

我无法给出完整的答案,但我可以告诉你,即使编译器生成了 unapply案例类的方法,当它在案例类上进行模式匹配时,它不使用该 unapply 方法。如果你尝试 -Ybrowse:typer使用内置大小写匹配和您的 unapply方法,你会看到一个非常不同的语法树产生(对于 match )取决于使用哪个。您还可以浏览后面的阶段,看看差异仍然存在。

为什么 Scala 不使用内置 unapply 我不确定,尽管这可能是您提出的原因。以及如何自己解决它unapply我不知道。但这就是 Scala 似乎神奇地避免了这个问题的原因。

经过实验,显然是这个版本的unapply有效,尽管我对为什么有点困惑:

def unapply[A,B](value: BlackOrWhite[A,B]): Option[B] = value match {
case w: White[_,_] => Some(w.right)
case _ => None
}

您的 unapply 的困难是编译器必须以某种方式确信如果 White[A,B]扩展了 BlackOrWhite[C,D]然后 BD 相同,显然编译器能够在这个版本中找到它,但在你的版本中却没有。不知道为什么。

关于Scala:案例类不适用与手动实现和类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8783226/

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