从实现中导入泛型 class 的隐式变量

Import implicit variable for generic class from implementation

我在 Scala 中遇到了一个问题,我真的很困惑。我知道标题可能更令人困惑,所以让我尝试尽可能简单地解释它。假设我有一个名为 Repoabstract class。 class 描述了一些关于它们的方法,其中大部分已经实现。 class Repo 看起来像这样:

abstract class Repo[T](name: String) {

  implicit def collection(implicit db: DefaultDB): JSONCollection =
    db.collection[JSONCollection](name)

  def findOne(selector: JsObject)(implicit collection: JSONCollection): Future[Option[T]] = {
    collection.find(selector).one[T]
  }

  ...

}

此 class 的基本实现如下所示:

import models.Models.Resume._

object ResumeRepo extends Repo[Resume]("resumes")

现在,如果我尝试编译它,它会给我一个错误,说:"No Json serializer found for type T. Try to implement an implicit Writes or Format for this type." 这很奇怪,因为我在 ResumeRepo 实现中明确包含隐式 Format class。为什么显示此错误?

我猜 one[T] 期望在其应用程序站点上可以访问隐式 Reads[T]。这意味着在 findOne 的定义中选择隐式,在 class Repo 中选择泛型类型 T。所以你需要让这样的隐式在那里可见。

你有三个选择。您可以添加 Reads[T]

类型的隐式参数
  • 找到一个:

    def findOne(selector: JsObject)(implicit collection: JSONCollection, readsT : Reads[T]) : ...
    

    那样的话,调用 findOne 时隐式必须可见。

  • as class 隐式参数:

    abstract class Repo[T](name: String)(implicit readsT : Reads[T]) { ...
    

这样它在 Repo 中的任何地方都可见,但它必须在继承和实例化站点上可见。例如,您不能将隐式放在 RepoResume 中,因为它必须在对象创建时可见。

  • 最后作为抽象的抽象值成员class

    abstract class Repo[T](name: String) {
       implicit val readsT : Reads[T]
     ...
    }
    
    object RepoResume extends Repo[Resume]("resume") {
       implicit val readsT : Reads[T] = ....
    }