简体   繁体   English

检查 Scala class 实例的运行时类型

[英]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:我的建议:

  1. I would bet you are not following an appropriate resource to learn the language.我敢打赌,您没有遵循适当的资源来学习该语言。 Rather, it seems you are just trying to mimic another language ( Python ?) with different syntax.相反,您似乎只是想用不同的语法模仿另一种语言Python ?) - Thus, I encourage you to pick an appropriate book, course, tutorial, etc; - 因此,我鼓励您选择合适的书籍、课程、教程等; that properly introduces the language and its idioms.正确地介绍了语言及其习语。
  2. I would encourage you to join the official Discord server which is more suitable for newcomers than StackOverflow.我鼓励你加入比 StackOverflow 更适合新手的官方Discord服务器
  3. I would recommend you to explain the meta-problem you are trying to solve in detail (either here in a new question or in the Discord server) , I am pretty sure there are better and more idiomatic ways to solve it.我建议您详细解释您要解决的元问题(在新问题中或在Discord服务器中) ,我很确定有更好、更惯用的方法来解决它。

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

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