在 Slick 3.0 中,为什么可以将 result 方法应用于 Query 对象?

In Slick 3.0, why could `result` method be applied to a `Query` object?

我正在使用 Slick 3.0:https://github.com/slick/slick/tree/3.0.0

示例代码如下所示:

class Coffees(tag: Tag) extends Table[(String, Double)](tag, "COFFEES") {
  def name = column[String]("COF_NAME", O.PrimaryKey)
  def price = column[Double]("PRICE")
  def * = (name, price)
}
val coffees = TableQuery[Coffees]
val coffeeNames: Future[Seq[Double]] = db.run(
  coffees.map(_.price).result
)

我认为coffees.map(_.price).result中的result方法在这里描述:

http://www.scala-lang.org/api/2.11.5/index.html#scala.collection.mutable.Builder@result():To

这是Builderclass.

的一个方法

不过,coffees.map(_.price)Queryclass而不是Builderclass,而Queryclass好像不是Builder class 的子class。此外,似乎没有从 Query class 到 Builder class 的隐式转换。并且 Query class 没有名为 result.

的方法

那么result是如何应用到Query对象上的。有人对此有想法吗?

result 方法不是来自 Builder class。它在 JdbcActionComponent.scala 文件中的 QueryActionExtensionMethodsImpl class 中定义。

在/slick/profile/BasicProfile.scala中,

  trait API extends CommonAPI with CommonImplicits {
    implicit def repQueryActionExtensionMethods[U](rep: Rep[U]): QueryActionExtensionMethods[U, NoStream] =
      createQueryActionExtensionMethods[U, NoStream](queryCompiler.run(rep.toNode).tree, ())
    implicit def streamableQueryActionExtensionMethods[U, C[_]](q: Query[_,U, C]): StreamingQueryActionExtensionMethods[C[U], U] =
      createStreamingQueryActionExtensionMethods[C[U], U](queryCompiler.run(q.toNode).tree, ())
    implicit def runnableCompiledQueryActionExtensionMethods[RU](c: RunnableCompiled[_, RU]): QueryActionExtensionMethods[RU, NoStream] =
      createQueryActionExtensionMethods[RU, NoStream](c.compiledQuery, c.param)
    implicit def streamableCompiledQueryActionExtensionMethods[RU, EU](c: StreamableCompiled[_, RU, EU]): StreamingQueryActionExtensionMethods[RU, EU] =
      createStreamingQueryActionExtensionMethods[RU, EU](c.compiledQuery, c.param)
    // Applying a CompiledFunction always results in only a RunnableCompiled, not a StreamableCompiled, so we need this:
    implicit def runnableStreamableCompiledQueryActionExtensionMethods[R, RU, EU, C[_]](c: RunnableCompiled[Query[R, EU, C], RU]): StreamingQueryActionExtensionMethods[RU, EU] =
      createStreamingQueryActionExtensionMethods[RU, EU](c.compiledQuery, c.param)
    // This only works on Scala 2.11 due to SI-3346:
    implicit def recordQueryActionExtensionMethods[M, R](q: M)(implicit shape: Shape[_ <: FlatShapeLevel, M, R, _]): QueryActionExtensionMethods[R, NoStream] =
      createQueryActionExtensionMethods[R, NoStream](queryCompiler.run(shape.toNode(q)).tree, ())
  }

有一个名为 repQueryActionExtensionMethods 的方法将 RepQuery 的超类)转换为 QueryActionExtensionMethods