[英]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
AbsChild
为AbsChild
所属的物理驱动器。 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.