How to avoid using asInstanceOf in Scala

Currently my code requires a class

val dataWriter: BytesDataWriter = createDataWriter

 def createDataWriter(p: SomeClass) =
    p.create_datawriter().asInstanceOf[BytesDataWriter]

      

The method create_datawriter

will return the superclass DataWriter. Instead of using it with asInstanceOf

, I tried this approach

val dataWriter: BytesDataWriter = createDataWriter(p)  match {
      case writer: BytesDataWriter => writer
      case _ => throw new ClassCastException
    }

      

It's too verbose and in case things don't work. Is there a better alternative to class?

+1


source to share


2 answers


You would use the second approach if you can do something about the result not BytesDataWriter

or get a better error message:

val dataWriter: BytesDataWriter = p.create_datawriter() match {
  case writer: BytesDataWriter => writer
  case other => throw new Exception(s"Expected p to create a BytesDataWriter, but got a ${other.getClass.getSimpleName} instead!")
}

      



Otherwise, use asInstanceOf

.

+6


source


The answer from Alexey Romanov is good advice for your specific situation. Alternatively, you can try to avoid this situation by changing the structure of the outer code.

Could your problem be reformulated?

When you use the class and instantiate it, it looks like you are implementing some kind of configuration handling for dependencies. This is a tricky problem, but luckily there are some good solutions for this:

Including dependencies

You can use some kind of dependency injection and inject as needed ByteDataWriter

with a special type. Check out the Robot Foot example described in the Google Guice FAQ for how to deal with different variants of the same base class, and how to deal with generics . This can help you avoid problems with DataWriter

and ByteDataWriter

.

Duck seal



You can also access yours DataWriter

using a protocol (or in Scala say: structured type ). Structural types will not be checked at compile time, so there is no need for cool casting.

Pie drawing

Or, you can handle your dependencies with a Scala specialty: the cake pattern . With this template, you can compose your class as needed. You can create a class that requires a type safe ByteDataWriter

. Then the compiler has to make sure that it can only match with the correct class. No class needed. The downside is that you cannot reconfigure dependencies using a config file. But this is usually not necessary because the supported options are well known at compile time.

Conclusion: try to reformulate when possible

If you have this option, consider redesigning your code using one of the methods above to get rid of the class. It is very likely that you will have the same problem in many other places in your code.

+4


source







All Articles