Reputation: 187
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.
Upvotes: 0
Views: 110
Reputation: 22850
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:
Upvotes: 2