加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:案例类未应用于手动实现和类型擦除

发布时间:2020-12-16 09:36:50 所属栏目:安全 来源:网络整理
导读:我正在试图了解Scala对Case Classes的作用,这使得它们以类型擦除警告的方式不受影响。 假设我们有以下简单的类结构。这基本上是一个: abstract class BlackOrWhite[A,B]case class Black[A,B]( val left: A ) extends BlackOrWhite[A,B]case class White[A
我正在试图了解Scala对Case Classes的作用,这使得它们以类型擦除警告的方式不受影响。

假设我们有以下简单的类结构。这基本上是一个:

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]

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]

使用-unchecked标记编译会发出以下警告:

[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来解决警告(到目前为止还没有用),但是这两个实现有什么区别?案例类是否需要添加内容?这可以用清单来规避吗?

我甚至尝试通过scala编译器运行case类实现,打开了-Xprint:typer标志,但是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);

提前致谢

解决方法

我不能给出完整的答案,但是我可以告诉你,尽管编译器为case类生成一个未应用的方法,但是当它在案例类上匹配时,它不使用该未应用的方法。如果您尝试使用–Browse:typer使用内置情况匹配和您的未应用方法,您将看到一个非常不同的语法树生成(对于匹配),取决于使用哪个。您也可以浏览后期阶段,看看差异依然存在。

为什么Scala不使用内置的unapply我不知道,虽然可能是因为你提出的原因。而且如何解决这个问题,我自己也没办法了。但这是Scala似乎幻想地避免这个问题的原因。

经过实验,显然这个版本的unapply作品,虽然我有点困惑为什么:

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

你的未应用的困难是,不知何故编译器必须相信,如果一个White [A,B]扩展了一个BlackOrWhite [C,D],那么B与D相同,这显然是编译器能够在这个版本,但不在你的。不知道为什么

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读