我正在与ZeroMQ和Akka集成,以便从不同的实例发送案例类。问题是当我尝试编译这段代码时:
def persistRelay(relayEvent:String, relayData:Any) = {
val relayData = ser.serialize(relayData).fold(throw _, identity)
relayPubSocket ! ZMQMessage(Seq(Frame(relayEvent), Frame(relayData)))
}
Scala编译器会抛出recursive value relayData needs type
。
进入的案例类别都不同,看起来像Team(users:List[Long], teamId:Long)
等等。
是否有方法允许序列化程序中的任何类型或解决方法?除非绝对必要,否则我宁愿避免为每个创建数据的函数编写一个序列化器。
谢谢!
答案 0 :(得分:3)
这不是真正的打字问题。问题是:
val relayData = ser.serialize(relayData).fold(throw _, identity)
您在同一行中声明了val relayData
,而您正在引用方法参数relayData
。 Scala编译器不理解您有/想要两个具有相同名称的变量,而是将其解释为val relayData
的递归定义。更改其中一个变量的名称应该可以解决错误。
无论如何,既然你没有完全遵循Scala编译器所要求的内容,我认为让你了解编译器甚至想要你的内容也是一件好事(尽管它的建议是,如果遵循,可能会导致你得到另一个错误,根据具体情况似乎没有多大意义。)
它说“递归值relayData
需要类型”。这意味着它希望您只需通过
relayData
的类型
val relayData = ...
变得像
val relayData: Serializable = ...
(或代替Serializable
,使用您希望relayData
拥有的任何类型
它需要此信息才能创建递归定义。例如,采用
的简单情况val x = x + 1
这个代码......奇怪,至少可以说,但我正在做的是以(浅)递归的方式定义x
。但是有一个问题:编译器如何知道内部x
使用什么类型?它无法通过类型推断真正确定类型,因为类型推断涉及利用其他定义的类型信息,此定义需要 x
类型信息。现在,我们可能能够推断出我可能正在谈论Int
,但理论上,x
可能这么多东西 !事实上,这是行动中的含糊不清:
val x: Int = x + 1 // Default value for an Int is '0'
x: Int = 1
val y: String = y + 1 // Default value for a String is 'null'
y: String = null1
真正改变的是类型注释,但结果却截然不同 - 这只是一个非常简单的案例!所以,是的,总结所有这些... 在大多数情况下,当它抱怨需要类型的递归值时,你应该对可怜的编译器有一些同情并给它类型信息非常渴望。 DeLongey会为你做同样的事情!它会为你做同样的事情!