简体   繁体   English

在这个使用泛型的例子中,asInstanceOf有什么问题吗?

[英]Is there anything wrong with asInstanceOf in this example using generics?

Consider this (somewhat contrived) example: 考虑这个(有点人为的)例子:

abstract class Obj[A, B] {
    def id: Long
    def parent: B
}

abstract class TopLevel[A] extends Obj[A, A] {
    def parent: A = this.asInstanceOf[A] // How terrible is this?
}

abstract class AbsChild[A, B] extends Obj[A, B] {
    def parent: B
}

case class Top(id: Long) extends TopLevel[Top]

case class Child(id: Long, parent: Top) extends AbsChild[Child, Top]

To paint a better picture, imagine AbsChild as some kind of directory on a file system, and TopLevel as the physical drive that an AbsChild belongs to. 要绘制更好的图片, AbsChild设想为文件系统上的某种目录,将TopLevel AbsChildAbsChild所属的物理驱动器。 So parent doesn't actually refer to the direct parent of the object (like the directory that contains it), but rather a reference to the top level object in the tree. 所以parent实际上并没有引用对象的直接父代(比如包含它的目录),而是引用树中的顶级对象。

In some applications, I'm going to be dealing with a List[Obj[A, B]] , where it isn't immediately known what Obj is. 在某些应用程序中,我将要处理List[Obj[A, B]] ,其中不知道Obj是什么。 In this case, it would be nice for even a TopLevel to have a parent , which should just return a reference to itself. 在这种情况下,这将是很好的,甚至一个TopLevel有一个parent ,这应该只是返回到自身的引用。 And herein lies my question. 这就是我的问题。

Defining def parent: A = this for TopLevel doesn't work: 定义def parent: A = this对于TopLevel不起作用:

<console>:14: error: type mismatch;
 found   : TopLevel.this.type (with underlying type TopLevel[A])
 required: A

But def parent: A = this.asInstanceOf[A] does, and seems to function correctly in practice. 但是def parent: A = this.asInstanceOf[A]确实如此,并且似乎在实践中正确运行。

scala> val top = Top(1)
top: Top = Top(1)

scala> val child = Child(1, top)
child: Child = Child(1,Top(1))

scala> top.parent
res0: Top = Top(1)

scala> child.parent
res1: Top = Top(1)

But is this really okay? 但这真的没问题吗? Using asInstanceOf[A] feels incredibly dirty, and leaves me wondering if it will fail somehow with a ClassCastException . 使用asInstanceOf[A]感觉非常脏,让我想知道它是否会因ClassCastException以某种方式失败。

You would get a ClassCastException if you had a subclass of TopLevel[A] that wasn't an A . 如果你有一个TopLevel[A]的子类不是A ,你会得到一个ClassCastException To avoid the need to cast you should use a self type (I'm not sure if that's the correct name): 为了避免需要施放你应该使用自我类型(我不确定这是否是正确的名称):

abstract class TopLevel[A] extends Obj[A, A] {
  this: A =>
    def parent: A = this
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM