【问题标题】:Scala and Play: how can I use my implicit object?Scala 和 Play:如何使用我的隐式对象?
【发布时间】:2015-12-04 06:29:35
【问题描述】:

隐式参数应该很容易,但到目前为止还不是。

我一直在使用 ReactiveMongo 在我的 Scala / Play 2.4 应用程序中保存和检索数据。一段时间以来,我一直在我的控制器中进行保存,但我想将代码移动到正在保存的实体的伴随对象中。这就是麻烦的开始。

以下是我的控制器的相关部分,展示了确实是如何工作的:

package controllers

...
import model.Destination
import model.Destination.DestinationBSONReader
import scala.concurrent.ExecutionContext.Implicits.global
...

  def add = Action { implicit request =>
    Destination.destinationForm().bindFromRequest.fold(
      formWithErrors => {
        implicit val helper = sfh(formWithErrors)
        BadRequest(views.html.addDestination(formWithErrors))
      },
      destinationData => {
        Destination.mongoCollection.insert(destinationData)
...
          Redirect("/destinations").flashing("success" -> s"The destination ${destinationData.name} has been created")
        }
      }
    )
  }

您可以想象一个表单正在提交,其中包含填充“目标”的数据,然后将其保存到 Mongo。 Destination 对象被导入,scala ExecutionContext 也是如此。我的“Destination”伴随对象有一个 BSONDocumentWriter[Destination] 的实例(mongoCollection.insert() 调用隐式需要),如下所示:

object Destination {

  ...

  implicit object DestinationBSONWriter extends BSONDocumentWriter[Destination] {
    override def write(destination: Destination): BSONDocument = {
      val dbId = if (destination.id.isDefined) { destination.id.get } else { BSONObjectID.generate.stringify }
      destination.newId = dbId
      BSONDocument(
          "id" -> dbId,
          ... lots of other key/value pairs,
      "name" -> destination.name)
    }
  }

  ...

}

现在,我想将 mongoCollection.insert(destinationData) 调用移至同一个“Destination”对象;控制器真的不应该与数据存储区对话。所以我创建了一个简单的方法,无论我做什么都会导致编译错误:

  def create(destination: Destination) = {
    Destination.mongoCollection.insert(destination)
  }

^- 编译失败; “找不到参数编写器的隐式值:reactivemongo.bson.BSONDocumentWriter[model.Destination]”

所以我在类的顶部添加了导入,因为 Scala 编译器应该在搜索隐式时查看导入:

import model.Destination.DestinationBSONWriter
import scala.concurrent.ExecutionContext.Implicits.global

^-同样的编译错误

所以我决定显式传递隐式参数:

  def create(destination: Destination) = {
    Destination.mongoCollection.insert(destination)(writer = DestinationBSONWriter, ec=global)
  }

^- 那会导致编译器挂起,我需要重新启动激活器。

我很困惑。该隐式参数就在同一对象中,但编译器没有检测到它。我应该如何使用它?

【问题讨论】:

  • 我一直在尝试各种排列。一旦我到达我认为它必须工作的任何一点,激活器就会挂起并且不会重新编译,就像我上面的最后一个示例一样。我怀疑这更像是一个 SBT 问题,而不是对隐式参数的误解。

标签: scala playframework-2.0


【解决方案1】:

经过一天的调查,SBT 显然存在问题。无论出于何种原因,只要它应该成功编译我的代码,它就决定挂起。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-23
    • 2013-03-08
    • 2020-11-24
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    相关资源
    最近更新 更多