我是 Scala 的新手,正在探索隐式转换和著名的蛋糕模式的可能性。我尝试创建将 id 值列为抽象类型的模型类,以避免泄漏实现细节。我还将它混合到蛋糕图案特征包装中。一切正常,除了从 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 实现,结果与错误相同。