Scala模式与类型类的类型参数匹配
然后,在其他地方我需要这样做:Scala模式与类型类的类型参数匹配,scala,playframework-2.0,pattern-matching,implicit-conversion,typeclass,Scala,Playframework 2.0,Pattern Matching,Implicit Conversion,Typeclass,然后,在其他地方我需要这样做: 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 在最后一个函数中,scalac/sbt不“理解”值可以转换为json(通过其隐式/类型类写
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
在最后一个函数中,scalac/sbt不“理解”值可以转换为json(通过其隐式/类型类写入[t]
)。我怎么写才能让它“明白”
(注意:
Writes[T]
来自Play Framework-它基本上说类型T=>JsValue
有一个隐式转换可用)您的问题是当您进行模式匹配时,Writes
隐式不在范围内;最简单的解决方案是保留对它的显式引用,以便在需要时使用它。这样,您的类定义将类似于:
def makeJson(fields: List[FormField]) = fields.map {
case StringField(name, value) => Json.obj(name -> value)
case ChoiceField(name, value, _) => Json.obj(name -> value)
}
与您的模式匹配:
case class ChoiceField[T](name: String, value: T, choices: List[T])(implicit val writes: Writes[T]) extends FormField
您的问题是当您进行模式匹配时,
写入
隐式不在范围内;最简单的解决方案是保留对它的显式引用,以便在需要时使用它。这样,您的类定义将类似于:
def makeJson(fields: List[FormField]) = fields.map {
case StringField(name, value) => Json.obj(name -> value)
case ChoiceField(name, value, _) => Json.obj(name -> value)
}
与您的模式匹配:
case class ChoiceField[T](name: String, value: T, choices: List[T])(implicit val writes: Writes[T]) extends FormField
“找不到任何类型的Json序列化程序。请尝试实现此类型的隐式写入或格式。”您不能创建一个
Writer[FormField]
实例来将StringField
或ChoiceField
转换为Json吗?如果我尝试创建一个Writes[FormField]
,我仍然需要进行模式匹配,我也会遇到同样的问题。(编辑:makeJson
这里基本上是一个Writes[FormField]
)“找不到任何类型的Json序列化程序。尝试实现此类型的隐式写入或格式。”您不能创建Writer[FormField]
实例,它可以将StringField
或ChoiceField
转换为json?如果我尝试创建写入[FormField]
,我仍然需要模式匹配,我会遇到完全相同的问题。(编辑:makeJson
这里基本上是一个写[FormField]
)嗯。顺便说一句,我打破了案例类的传统“规则”了吗?现在case类有两个参数列表,写操作根本不意味着“模式匹配”。这是讨厌的代码吗。。?我还能做什么?我不认为这里有任何违反规则的地方:定义为[t:Writes]
的上下文绑定只是隐式参数的语法糖;如果你想写的话,你可以把它写成case-class-ChoiceField[T:Writes](name:String,value:T,choices:List[T]){lazy-val-Writes=隐式[Writes[T]}
,但最终还是一样的。老实说,我对play json的了解可能还不够多,因此没有想到比这更聪明的方法。在case类上进行模式匹配时,只考虑第一个参数列表。其他参数列表(如果有的话)与标准类中的参数列表没有什么不同:它们只是类的主构造函数的普通参数。顺便说一句,我是否打破了案例课程的常规“规则”?现在case类有两个参数列表,写操作根本不意味着“模式匹配”。这是讨厌的代码吗。。?我还能做什么?我不认为这里有任何违反规则的地方:定义为[t:Writes]
的上下文绑定只是隐式参数的语法糖;如果你想写的话,你可以把它写成case-class-ChoiceField[T:Writes](name:String,value:T,choices:List[T]){lazy-val-Writes=隐式[Writes[T]}
,但最终还是一样的。老实说,我对play json的了解可能还不够多,因此没有想到比这更聪明的方法。在case类上进行模式匹配时,只考虑第一个参数列表。其他参数列表(如果有的话)与标准类中的参数列表没有什么不同:它们只是类的主构造函数的普通参数。