从实现

时间:2015-05-24 19:25:41

标签: scala playframework reactivemongo

我在Scala中遇到了一个问题我真的被困住了。我知道标题可能更令人困惑,所以让我尽量解释它。想象一下,我有abstract class名为Repo。这个类描述了几个方法,其中大部分已经实现。班级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]
  }

  ...

}

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

import models.Models.Resume._

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

现在,如果我尝试编译它,它会给我一个错误,说:“找不到类型为T的Json序列化程序。尝试为此类型实现隐式写入或格式化。”这很奇怪,因为我在Format实现类中明确包含了隐式ResumeRepo。为什么会显示此错误?

1 个答案:

答案 0 :(得分:1)

I guess that one[T] expects an implicit Reads[T] to be accessible at its application site. Which means the implicit is selected in the definition of findOne, in the class Repo, for the generic type T. So you need to make such an implicit visible there.

You have three options. You can add an implicit argument of type Reads[T]

  • to findOne :

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

    That way the implicit has to be visible when findOne is called.

  • as class implicit argument:

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

That way it is visible anywhere in Repo but it must be visible at inheriting and instantiating site. For example you can't put the implicit in RepoResume because it has to be visible at object creation.

  • finaly as abstract value member of the abstract class

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