简体   繁体   English

将案例类的伴随对象用作类型参数时编译错误

[英]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? 你的意思是将FooBar的构造函数传递给它吗? If so, you should do Foo.apply and Bar.apply . 如果是这样,你应该做Foo.applyBar.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM