检查 Scala class 实例的运行时类型
Check the runtime type of Scala class instance
如果我运行下面的代码,然后我得到一个错误:
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()
}
那是因为General没有函数test()。
我知道我可以通过模式匹配来解决这个问题。这代替了上面的 funcForSubGeneral() 工作:
def funcForSubGeneral(): Unit =
array(0)(0) match {
case s: SubGeneral => s.test()
case _ => println("nope")
}
但我想知道是否有可能获取 运行time 类型的数组(0)(0) 并检查它是否是 SubGeneral,如果是这样,那么我调用 test( ), 这应该不会引起问题?
这就是我实际尝试使用 isIntanceOf 的目的。我想省略模式匹配,因为我只对一种类型感兴趣。
isInstanceOf
不会改变任何东西,您需要执行 array(0)(0).asInstanceOf[SubGeneral].test()
才能强制转换。
请注意,转换可能会在运行时失败,因此您需要先检查 if
。因此,最终代码如下所示:
if (array(0)(0).isInstanceOf[SubGeneral]) then array(0)(0).asInstanceOf[SubGeneral].test()
但是,由于这很麻烦且容易出错,我们有模式匹配:
array(0)(0) match {
case subGeneral: SubGeneral => subGeneral.test()
}
但是请注意,类型测试被认为是一种不好的做法;主要是因为它们实际上是 class 检查并且可能会在某些情况下失败。例如:
List("a", "b", "c") match {
case numbers: List[Int] => numbers.head + 1
}
将在运行时抛出异常,因为由于类型擦除,我们丢失了 [String]
部分并且它仅匹配 List
然后它尝试将第一个元素读取为 Int
这是一个错误。
无论如何,这是您在两天内第四次提出显示不良做法和不合常理的代码的问题。
我的建议:
- 我敢打赌您没有按照适当的资源来学习这门语言。相反,您似乎只是想用不同的语法模仿另一种语言 (Python?) 。 - 因此,我鼓励您选择合适的书籍、课程、教程等;正确介绍了该语言及其习语。
- 我鼓励你加入比 Whosebug 更适合新手的 official Discord server。
- 我建议你详细解释你试图解决的元问题(在新问题中或在 Discord 服务器中) ,我很确定有更好更惯用的方法来解决它。
如果我运行下面的代码,然后我得到一个错误:
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()
}
那是因为General没有函数test()。 我知道我可以通过模式匹配来解决这个问题。这代替了上面的 funcForSubGeneral() 工作:
def funcForSubGeneral(): Unit =
array(0)(0) match {
case s: SubGeneral => s.test()
case _ => println("nope")
}
但我想知道是否有可能获取 运行time 类型的数组(0)(0) 并检查它是否是 SubGeneral,如果是这样,那么我调用 test( ), 这应该不会引起问题? 这就是我实际尝试使用 isIntanceOf 的目的。我想省略模式匹配,因为我只对一种类型感兴趣。
isInstanceOf
不会改变任何东西,您需要执行 array(0)(0).asInstanceOf[SubGeneral].test()
才能强制转换。
请注意,转换可能会在运行时失败,因此您需要先检查 if
。因此,最终代码如下所示:
if (array(0)(0).isInstanceOf[SubGeneral]) then array(0)(0).asInstanceOf[SubGeneral].test()
但是,由于这很麻烦且容易出错,我们有模式匹配:
array(0)(0) match {
case subGeneral: SubGeneral => subGeneral.test()
}
但是请注意,类型测试被认为是一种不好的做法;主要是因为它们实际上是 class 检查并且可能会在某些情况下失败。例如:
List("a", "b", "c") match {
case numbers: List[Int] => numbers.head + 1
}
将在运行时抛出异常,因为由于类型擦除,我们丢失了 [String]
部分并且它仅匹配 List
然后它尝试将第一个元素读取为 Int
这是一个错误。
无论如何,这是您在两天内第四次提出显示不良做法和不合常理的代码的问题。
我的建议:
- 我敢打赌您没有按照适当的资源来学习这门语言。相反,您似乎只是想用不同的语法模仿另一种语言 (Python?) 。 - 因此,我鼓励您选择合适的书籍、课程、教程等;正确介绍了该语言及其习语。
- 我鼓励你加入比 Whosebug 更适合新手的 official Discord server。
- 我建议你详细解释你试图解决的元问题(在新问题中或在 Discord 服务器中) ,我很确定有更好更惯用的方法来解决它。