Erasable bypass as per pattern

I am trying to work with type erasure according to pattern. Assuming that:

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 the map, and there is no way to provide a class manifest.

Any bizarre stunt extractor?

+6
source share
2 answers

Well, the question has a peculiar precondition (as I understand it) - we can select the Serializer in the serializer and deserializer. Obviously, when I have an instance of V , my use case is serialization, and the return type does not require V Thus,

 trait Serializer { def save(os: OutputStream): Unit } 

it would be enough, and any type can mix it. 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 will either provide a deserializer along with the Ref[V] string, or rely on a class search through ObjectInputStream .

+2
source

If you can make a Serializer instead of an abstract class, you can specify Manifest as an implicit constructor parameter and use it to create a specific class when building, and then use it later to check the dynamic type.

 import java.io._ abstract class Serializer[V: Manifest] { def save(os: OutputStream, v: V): Unit def load(in: InputStream): V val clazz = manifest[V].erasure } val ser = new Serializer[Int] { def save(os: OutputStream, v: Int) { os.write((v.toString + "\n").getBytes) } def load(in: InputStream) = { val line = new BufferedReader(new InputStreamReader(in)).readLine() line.toInt } } ser.clazz // java.lang.Class[_] = int 
+4
source

Source: https://habr.com/ru/post/885922/