Home > Net >  Check the runtime type of Scala class instance
Check the runtime type of Scala class instance

Time:12-29

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(). I know that I can fix this with pattern matching. This instead of the above funcForSubGeneral() works:

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? That is what I was actually trying by using isIntanceOf. I want to omit pattern matching since I'm just interested in one type.

CodePudding user response:

isInstanceOf doesn't change anything, you would need to do array(0)(0).asInstanceOf[SubGeneral].test() in order to force the casting.


Note that the casting may fail at runtime, so that is why you need to check with the if before. 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. 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.


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. - 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.
  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.
  • Related