我是 Scala 新手,正在探索隐式转换和著名蛋糕模式的可能性。我尝试创建将 id 值列为抽象类型的模型类,以避免泄漏实现细节。我还将它混合到蛋糕图案特征 wrapper 中。除了从 id 到 JSON 的隐式转换(在 Play 框架内)之外,一切正常。无论我做什么,Scala 编译器都找不到隐式转换。
这是重现问题的代码:
import anorm._
import play.api.libs.json._
trait Card {
type Key
val NoId: Key
val id: Key
val name: String
}
trait CardModelComponent {
val cardModel: CardModel
trait CardModel {
def findById(id: Long): Option[Card]
def findAll: Seq[Card]
def delete(id: Long)
def create(name: String): Option[Card]
}
}
trait CardModelComponentImpl extends CardModelComponent {
case class CardImpl(id: Pk[Long], name: String) extends Card {
type Key = Pk[Long]
object Key extends Writes[Key] {
implicit def writes(key: Key): JsValue = {
key match {
case Id(idVal: Long) => JsNumber(idVal)
case _ => JsNull
}
}
}
val NoId = NotAssigned
}
class CardModelImpl extends CardModel {
def findById(id: Long): Option[Card] = { None }
def findAll: Seq[Card] = { Seq(CardImpl(Id(1), "Some card"))}
def delete(id: Long) {}
def create(name: String): Option[Card] = { Some(CardImpl(Id(1), name)) }
}
}
object ComponentsRegistry extends
CardModelComponentImpl {
val cardModel = new CardModelImpl
}
val card = ComponentsRegistry.cardModel.create("Test card").get
Json.toJson(card.id)
我得到的错误输出如下:
> card: Card = CardImpl(1,Test card)
> <console>:19: error: No Json deserializer found for type card.Key. Try to implem
ent an implicit Writes or Format for this type.
Json.toJson(card.id)
^
有什么办法可以让它发挥作用吗?看起来蛋糕模式包装对编译器隐藏了太多类型信息,正如我从 card.Key
类型名称中猜测的那样。
我还尝试直接为 Pk 创建 Writer 实现,但出现与结果相同的错误。
最佳答案
应该是隐式的 Writes[Key]
实例,而不是 writes()
成员方法。隐式实例还必须位于调用 toJson()
方法的范围内。
关于scala - Scala中抽象类型参数的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14308911/