Scala – Checking for Type and Casting

scala

I have sometimes the usecase that I need to check if a variable is of a specific type and if so cast to it to access a property/function of it.

Example:

    if (state.isInstanceOf[StateA] && state.asInstanceOf[StateA].isFlagBlaBla)

How can this be improved ? I could use match/case but is there a better option (shorter) ?

Best Answer

The shorter way is to architect your application so your variable already has .isFlagBlaBla, either by making state already an instance of StateA, or by making .isFlagBlaBla a method of the base class you're using. This is basic SOLID OOP design principles. If you post more context in another question, we could help you refactor.

Aside from that, there's really no way to shorten this, other than extracting it into a function. Functional languages let you simplify almost anything by extracting it into a function. You can always write an abomination like the following:

  class BaseState() {
    import scala.reflect.{ClassTag, classTag}

    def castAndTest[A: ClassTag](f: A => Boolean): Boolean =
      if (classTag[A].runtimeClass.isInstance(this)) f(this.asInstanceOf[A])
      else false
  }

  class StateA() extends BaseState {
    def isFlagBlaBla = true
  }

  def main(args: Array[String]) {
    val baseState: BaseState = new BaseState()
    val stateA:    BaseState = new StateA()

    baseState castAndTest[StateA] {_.isFlagBlaBla} // returns false
    stateA    castAndTest[StateA] {_.isFlagBlaBla} // returns true
  }

Type casts are extremely rare in languages with type systems as powerful as Scala's. I've literally never had to do one in Scala, and didn't even remember the syntax. Even in languages with medium-strength type systems, they should be heavily scrutinized.

Related Topic