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不太瞭解,想要提出一些比這更聰明的東西。 –