url (本质上)是一个返回Req 对象的方法。所以request 的类型为Req。
Http 是一个带有伴生对象的类,该对象有几个apply 方法的重载。所以当你看到:
Http(request OK as.String)
它实际上是语法糖:
Http.apply(request OK as.String)
好的,那么apply 内部发生了什么?似乎在 request 上调用了一个名为 OK 的方法。但是查看API Docs,您可能会注意到Req 类型没有这种方法OK。然而,有一个名为RequestHandlerTupleBuilder 的类确实有这样的方法。 dispatch 包中定义了一个隐式转换:
implicit def implyRequestHandlerTuple(builder: Req) =
new RequestHandlerTupleBuilder(builder)
这里发生的情况是,当您调用request OK 时,编译器会看到request 没有OK 方法。因此,它会寻找可能的隐式方法,这些方法接受Req 作为参数并返回类型以拥有这样的方法。上面的方法是它找到的隐式,所以Req被隐式转换为RequestHandlerTupleBuilder。
现在我们来看OK的签名:
def OK [T](f: Response => T): (Request, OkFunctionHandler[T])
它接受一个函数作为参数。特别是,接受Response 作为参数并返回一些其他类型T 的函数。在这种情况下,这样的函数是as.String,其类型为Response => String。然后OK 将返回一个Request 与OkFunctionHandler[T] 的元组。
这告诉我我们调用的apply 的重载是这个:
def apply[T](pair: (Request, AsyncHandler[T])): Future[T]
(OkFunctionHandler 扩展AsyncHandler)
以更类似于 java 的风格和类型注释来查看所有内容,您有:
val request: Req = url("http://somesite.com")
val result: Future[String] = Http.apply(request.OK(as.String))
仅使用显式调用,它看起来更像:
val result: Future[String] =
Http.apply(implyRequestHandlerTuple(request).OK(as.String))
简而言之,只有一个参数被传递给Http.apply,它只是使用无点样式调用其中的其他方法。