Scala中抽象类型参数的隐式转换
发布时间:2020-12-16 10:02:39 所属栏目:安全 来源:网络整理
导读:我是 Scala的新手,探索隐式转换和着名蛋糕模式的可能性.我尝试创建模型类,其id值列为抽象类型,以避免泄漏实现细节.我也把它混合成蛋糕模式特质包装.一切正常,除了从id到 JSON的隐式转换(在Play框架内).无论我做什么,Scala编译器都找不到隐式转换. 这是重现问
我是
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实现,结果出现相同的错误. 解决方法
就像Je??sper Nordenberg写的那样,你必须将Writes [Key]的实例纳入范围.这样做的一种方法是要求Card的实现发布Writer实例,然后导入你调用toJson的那个,如下所示:
… trait Card { type Key val NoId: Key val id: Key val name: String implicit val Key: Writes[Key] } … trait CardModelComponentImpl extends CardModelComponent { case class CardImpl(id: Pk[Long],name: String) extends Card { type Key = Pk[Long] implicit object Key extends Writes[Key] { 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),name)) } } } … val card = ComponentsRegistry.cardModel.create("Test card").get import card.Key Json.toJson(card.id) 或明确传递: val card = ComponentsRegistry.cardModel.create("Test card").get Json.toJson(card.id)(card.Key) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |