[英]Compile error when using a companion object of a case class as a type parameter
I'm create a number of json messages for spray in scala using case classes. 我使用case类创建了一些用于在scala中喷涂的json消息。 For example: 例如:
case class Foo(name: String, attrs: List[String])
implicit val fooFormat = jsonFormat2(Foo)
object Foo {
case class Invalid(error: String)
}
case class Bar(name: String, kv: Map[String, String])
implicit val barFormat = jsonFormat2(Bar)
In the above snippet, barFormat
compiles, but fooFormat
does not: 在上面的代码片段中, barFormat
编译,但fooFormat
不会:
type mismatch; found : Foo.type required: (?, ?) => ?
Note: implicit value barFormat is not applicable here because it comes
after the application point and it lacks an explicit result type
I don't want to use barFormat
in place of fooFormat
, and I understand that a case class automatically generates a companion object, but I don't understand why there's a compiler error here, and the error message is difficult for me to decipher. 我不想使用barFormat
代替fooFormat
,我理解case类自动生成一个伴随对象,但是我不明白为什么这里有编译器错误,并且我很难解密错误消息。 Does anyone know what the problem is here and how to fix it, preferably without removing my Foo
companion object? 有谁知道这里的问题是什么以及如何解决它,最好不要删除我的Foo
伴侣对象?
From your compile error, it looks like jsonFormat2
expects a two-argument function. 从编译错误看, jsonFormat2
看起来像是一个双参数函数。 Do you mean to pass the constructors of Foo
and Bar
into it? 你的意思是将Foo
和Bar
的构造函数传递给它吗? If so, you should do Foo.apply
and Bar.apply
. 如果是这样,你应该做Foo.apply
和Bar.apply
。
Case class companion objects will by default extend one of the function traits. Case类伴随对象默认会扩展其中一个函数特征。 object Foo
would have extended ((String, List[String]) => Foo)
but when you manually defined it you didn't extend that trait. object Foo
会扩展((String, List[String]) => Foo)
但是当你手动定义它时你没有扩展那个特性。 This is why you couldn't pass it to jsonFormat2
, which was expecting a (?, ?) => ?
这就是为什么你不能把它传递给jsonFormat2
,它期待一个(?, ?) => ?
. 。 If you make the following change your code should compile: 如果进行以下更改,则应编译代码:
object Foo extends ((String, List[String]) => Foo) {
Spray.json documentation suggests an easier way than @wingedsubmariner's suggestion: Spray.json 文档提供了比@ wingedsubmariner的建议更简单的方法:
If you explicitly declare the companion object for your case class the notation above will stop working. 如果您明确声明了案例类的伴随对象,则上述符号将停止工作。 You'll have to explicitly refer to the companion object's
apply
method to fix this: 您必须明确引用随播对象的apply
方法来解决此问题:
So the correction for the question becomes: 因此,对问题的更正变为:
implicit val fooFormat = jsonFormat2(Foo.apply)
Added: This is in fact what also @geoffliu suggests in his answer. 补充:这实际上也是@geoffliu在他的回答中所暗示的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.