[英]Check the runtime type of Scala class instance
If I run the following code, then I get an error:如果我运行以下代码,则会收到错误消息:
import scala.reflect.ClassTag
class General {
}
class SubGeneral extends General {
def test() = println("tested")
}
class ProGeneral[T <: General: ClassTag] {
var array = Array.ofDim[T](3, 3)
def funcForSubGeneral(): Unit =
if (array(0)(0).isInstanceOf[SubGeneral]) then array(0)(0).test()
}
That is because General does not have the function test().那是因为General没有function test()。 I know that I can fix this with pattern matching.
我知道我可以通过模式匹配来解决这个问题。 This instead of the above funcForSubGeneral() works:
这代替了上面的 funcForSubGeneral() 工作:
def funcForSubGeneral(): Unit =
array(0)(0) match {
case s: SubGeneral => s.test()
case _ => println("nope")
}
But I was wondering if it is possible to get the runtime type of array(0)(0) and check if it is a SubGeneral, and if that is the case then I call test(), which shouldn't cause a problem?但是我想知道是否有可能获取 array(0)(0) 的运行时类型并检查它是否是 SubGeneral,如果是这种情况,那么我调用 test(),这不会导致问题吗? That is what I was actually trying by using isIntanceOf.
这就是我使用 isIntanceOf 实际尝试的。 I want to omit pattern matching since I'm just interested in one type.
我想省略模式匹配,因为我只对一种类型感兴趣。
isInstanceOf
doesn't change anything, you would need to do array(0)(0).asInstanceOf[SubGeneral].test()
in order to force the casting. isInstanceOf
不会改变任何东西,您需要执行array(0)(0).asInstanceOf[SubGeneral].test()
才能强制转换。
Note that the casting may fail at runtime, so that is why you need to check with the if
before.请注意,强制转换可能在运行时失败,这就是为什么您需要检查
if
之前的原因。 Thus the end code looks like this:因此最终代码如下所示:
if (array(0)(0).isInstanceOf[SubGeneral]) then array(0)(0).asInstanceOf[SubGeneral].test()
But, since this is cumbersome and error-prone, we have pattern matching:但是,由于这很麻烦且容易出错,我们有模式匹配:
array(0)(0) match {
case subGeneral: SubGeneral => subGeneral.test()
}
However, note that type tests are considered a bad practice;但是,请注意,类型测试被认为是一种不好的做法; mainly because they are actually class checks and may fail certain circumstances.
主要是因为它们实际上是 class 检查并且在某些情况下可能会失败。 For example:
例如:
List("a", "b", "c") match {
case numbers: List[Int] => numbers.head + 1
}
Will throw an exception in runtime since, due to type erasure, we lost the [String]
part and it matches only List
then it tries to read the first element as an Int
which is an error.将在运行时抛出异常,因为由于类型擦除,我们丢失了
[String]
部分并且它仅匹配List
然后它尝试将第一个元素作为Int
读取,这是一个错误。
Anyways, this is the fourth time in two days you ask a question that shows bad practices and unidiomatic code.无论如何,这是您两天内第四次提出一个显示不良做法和单一代码的问题。
My advice:我的建议:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.