0
sealed trait FormField 
case class StringField(name: String, value: String) extends FormField 
case class ChoiceField[T : Writes](name: String, value: T, choices: List[T]) extends FormField 

然后,别的地方我需要这样做:Scala的模式匹配类型为Class的类型参数

def makeJson(fields: List[FormField]) = fields.map { 
    case StringField(name, value) => Json.obj(name -> value) 
    case ChoiceField(name, value, _) => Json.obj(name -> value) 
} 

在最后一种功能,scalac/SBT不“理解”是value是可转换为json(通过其隐式/类型类Writes[T])。我怎么写它,以便它“得到它”?

(注:Writes[T]是玩框架 - 它基本上说,没有缴费的类型T => JsValue隐式转换)

+0

case class ChoiceField[T](name: String, value: T, choices: List[T])(implicit val writes: Writes[T]) extends FormField 

而且你的模式匹配“未找到任何类型的JSON序列尝试实施这种类型的隐写或格式。” – kornfridge

+0

你不能创建一个'Writer [FormField]'实例,它可以将'StringField'或'ChoiceField'变成json吗? –

+0

如果我试图创建'Writes [FormField]',我仍然需要模式匹配,并且我会有完全相同的问题。 (编辑:'makeJson'在这里_is_基本上''写[FormField]') – kornfridge

回答

3

你的问题是Writes隐含不在范围内,当你做模式匹配;最简单的解决方案是保持明确的引用,以便在需要时使用它。这样,你的类定义变得像:

case cf @ ChoiceField(name, value, _) => 
    implicit val tWrites = cf.writes 
    Json.obj(name -> value) 
+0

这是行得通的。谢谢! – kornfridge

+0

嗯。我在这里违反传统的案例类的“规则”吗?现在案例类有两个参数列表,写入不完全是“模式匹配”。这是不好的代码..?我还可以做些什么? – kornfridge

+1

我不认为这里有任何规则的破坏:定义为“[T:Writes]”的上下文绑定只是隐式参数的语法糖;如果你想要,你可以将它写成case case ChoiceField [T:Writes](name:String,value:T,choices:List [T]){lazy val writes = implicitly [Writes [T]]}'但是最终它是一回事。说实话,我可能对play-json不太了解,想要提出一些比这更聪明的东西。 –