我正在搜索一个方法的正确签名,该方法接受函数func和参数arg,通过网络将它们复制到远程计算机并返回结果。目前,签名如下:
def invokeRemote[A,B](address: String, func: A => B, arg: A): B这方面的问题是,如果参数不是可序列化的或Java的基本类型之一,则该方法将抛出一个NotSerializable异常。
我想出了以下解决方案,以便在编译时捕获此错误.
type Func = (A => B) with Serializable
def invokeRemote[A <: Serializable, B <: Serializable](address: String, func: Func, arg: A): B..。但是,现在不可能传递AnyVal类型的参数,如Int、Float或Double,这些参数没有显式实现可序列化。
如果方法签名只接受可序列化对象或AnyVal类型的对象作为参数,那么方法签名应该是什么样的呢?
发布于 2011-05-14 15:47:58
您可以使用带有自定义特征的隐式context bound,并为AnyVal和Serializable提供对该特征的隐式转换。
trait Ser[M]
implicit def toSer1[T <: AnyVal]: Ser[T] = new Ser[T] {}
implicit def toSer2[T <: java.io.Serializable]: Ser[T] = new Ser[T] {}
def f[T: Ser](a:T): T = a
f(1)
// res2: Int = 1
f("123")
// res3: java.lang.String = 123
f(new Object)
// could not find implicit value for evidence parameter of type Ser[java.lang.Object]编译器将根据类型查找隐式参数,因为有些参数是为T <: AnyVal和T <: java.io.Serializable提供的,因此在这种情况下将进行编译。
您可以将隐式定义放在Ser的配套对象中,以便在需要时可以使用它们。
然后,你的签名变成:
def invokeRemote[A:Ser, B:Ser](address: String, func: A => B, arg: A): B发布于 2012-09-02 17:40:39
使用Serializable作为参数类型在实践中不起作用,因为您可以拥有实际上无法序列化的可序列化实例:
class NotSerializable(val s: String)
// ArrayList inherits Serializable
val list = new java.util.ArrayList[NotSerializable]()
list.add(new NotSerializable("test"))
// will fail at run time
serialize(list)此外,Scala集合特性不能继承Serializable (实现是这样的)。
def f(s: Serializable) { println(s) }
// will fail to compile, because interface List does not inherit Serializable
f(List("a", "b"))
// will print true because list implementation is Serializable
println(List("a", "b").isInstanceOf[Serializable])Serializable是一个运行时属性,不能单独由类型强制执行。使用Serializable作为参数类型不会使您免于运行时序列化错误。您所要完成的就是让您的功能更难调用,因为您已经在使用AnyVal (而这只是冰山一角)。
https://stackoverflow.com/questions/6002722
复制相似问题