【问题标题】:Parametric polymorphism breaks when an implicit is expected in Scala当 Scala 中需要隐式时,参数多态性会中断
【发布时间】:2016-10-14 17:36:38
【问题描述】:

我明白了

没有找到类型 T 的 Json 序列化程序。尝试为此类型实现隐式写入或格式。

import play.api.libs.json._

trait A[T] {
  def foo(t: T) = bar(Json.toJson(t))
}

我将为 actual 参数类型提供Writes,但我认为这不会清除编译错误。经过一番谷歌搜索后,我觉得我对这个主题的理解可能缺少一些基本的东西。任何帮助表示赞赏。

【问题讨论】:

  • 我觉得应该是Json.toJson 对吗?
  • @pamu 是的,谢谢!修改它。

标签: scala implicit parametric-polymorphism


【解决方案1】:

在这种情况下,错误消息不是很清楚——你不需要为这种类型实现Writes,你只需要向编译器证明你有一个:

import play.api.libs.json._

trait A[T] {
  def foo(t: T)(implicit w: Writes[T]) = bar(Json.toJson(t))
}

这将按预期工作。您还可以在特征中包含implicit def w: Writes[T],这将要求实例化器提供一个实例,这更具限制性,因为您无法在没有实例的情况下实例化A,但如果您有一个实例,它在语法上会更简洁一些很多这样的方法,你实际上可能希望更早地启动限制,而不是在你已经实例化了 A 并且你试图调用 foo 之后。

【讨论】:

    【解决方案2】:

    提供implicit def writes

    import play.api.libs.json._
    
    trait A[T] {
      implicit def writes: Writes[T]
      def foo(t: T) = bar(Json.toJson(t))
    }
    

    或将写入作为implicit 参数提供给foo

    import play.api.libs.json._
    
    trait A[T] {
      def foo(t: T)(implicit writes: Writes[T]): JsValue = bar(Json.toJson(t))
    }
    

    【讨论】:

    • 抱歉,这是错误的——在您的第二个示例中,方法中的 T 将影响特征上的那个,这绝不是您想要的,并且可能导致极其混乱的问题。跨度>
    • @TravisBrown 编辑了答案。谢谢推荐
    • 但这完全改变了 OP 的 A 的语义。 :)
    • @TravisBrown 看起来像implicit 参数是要走的路.. 编辑了答案。谢谢建议
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2012-04-27
    • 1970-01-01
    相关资源
    最近更新 更多