我正在尝试在模式匹配中解决类型擦除问题。假设:
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] }
如何在没有警告且没有asInstanceOf
的情况下进行编译:
def test[V](os: OutputStream, v: V): Unit = v match {
case hs: HasSerializer[V] => hs.serializer.save(os, v)
case _ => ???
}
?使用地图中的值调用test
,并且无法提供类清单。
任何花哨的提取器技巧都可能?
答案 0 :(得分:4)
如果你可以使Serializer成为一个抽象类,你可以给它一个Manifest作为一个隐式的构造函数参数,并使用它来构造具体的类,然后再用它来进行动态类型检查。
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
答案 1 :(得分:2)
这个问题有一个错误的前提条件(正如我刚才所知) - 我们可以将Serializer
分成一个序列化器和一个解串器。显然,当我有V
的实例时,我的用例是序列化,并且不需要V
作为返回类型。因此
trait Serializer { def save(os: OutputStream): Unit }
就足够了,任何类型都可以混合使用。并且可以:
def testSer[V](os: OutputStream, v: V): Unit = v match {
case s: Serializer => s.save(os)
case _ => new ObjectOutputStream(os).writeObject(v)
}
对于反序列化,我们要么提供反序列化器以及构造Ref[V]
,要么依赖于ObjectInputStream
的类查找。