I am trying to work around a type erasure in pattern matching. Assuming:
import java.io._
trait Serializer[V] {
def save(os: OutputStream, v: V): Unit
def load(in: InputStream): V
}
trait HasSerializer[V] { def serializer: Serializer[V] }
How can I get this to compile without warning and without asInstanceOf
:
def test[V](os: OutputStream, v: V): Unit = v match {
case hs: HasSerializer[V] => hs.serializer.save(os, v)
case _ => ???
}
? test
is called with a value from a map and there is no means to provide a class manifest.
Any fancy extractor trick maybe?
Well the question has kind of a wrong precondition (as I just realize) -- we can take Serializer
apart into a serializer and a deserializer. Obviously, when I have an instance of V
, my use case is serialization, and that doesn't require V
as a return type. Thus
trait Serializer { def save(os: OutputStream): Unit }
would suffice, and any type can mix that in. And do:
def testSer[V](os: OutputStream, v: V): Unit = v match {
case s: Serializer => s.save(os)
case _ => new ObjectOutputStream(os).writeObject(v)
}
And for deserialization, we would either provide the deserializer along with the construction of a Ref[V]
, or rely on class lookup through ObjectInputStream
.