Scala 调度示例
Scala dispatch example
我是一名Java工程师,最近一直在慢慢学习Scala。我遇到了一些使用 Dispatch 发出简单 GET 请求的示例代码:
val request = url("http://somesite.com")
val result = Http( request OK as.String)
问题是...我不太明白这里发生了什么。首先,Http是class吗?还是一种方法?其次,传递给它的参数是怎么回事?我想也许我们传递了三个参数,Scala 允许我们省略逗号。但是当我尝试添加逗号时,我遇到了编译错误,所以这不对。
我相信这对精通 Scala 的人来说是有意义的,但我还没有做到这一点,它阻碍了我。我试过在线查找文档,但没有找到任何帮助。
这是一个(痛苦的)显式版本,去掉了所有语法糖:
import dispatch.{ Defaults, Http, Req, as, implyRequestHandlerTuple, url }
import scala.concurrent.Future
val request: Req = url.apply("http://somesite.com")
val result: Future[String] =
Http.apply(
implyRequestHandlerTuple(request).OK[String](as.String)
)(Defaults.executor)
url
is a singleton object with an apply
method that returns an instance of the Req
case class. Http
is also a singleton object, and it also has an apply
method. Http
's apply
takes two parameter lists—the first taking a single Req
parameter, and the second taking an execution context (which you can think of as Scala's version of Java's Executor
).
implyRequestHandlerTuple
是一种 隐式 方法。 Req
没有 OK
方法,但编译器知道 RequestHandlerTupleBuilder
class 有(并且它采用适当的参数——在本例中是来自 Response
到某种类型),因此在原始版本中它会自动应用此方法从 Req
.
进行转换
最后,as
是一个包含 String
单例对象的包。这个对象扩展了 Response => String
(这是 [=29= 的更多语法糖)。我们的 OK
方法正在寻找一个采用 Response
的函数,所以我们在那里很好。
最后你得到了 Future[String]
。有很多other places阅读关于期货,所以我不会在这里详细介绍,但简而言之,这个值可以是不满意的(即你还在等待结果),或者对失败感到满意(在网络错误等情况下),或成功满足(在这种情况下它将包含响应主体)。
url
是(本质上)一种 return 是 Req
对象的方法。所以 request
的类型是 Req
.
Http
是一个带有伴生对象的 class,它有一些 apply
方法的重载。所以当你看到:
Http(request OK as.String)
它实际上是语法糖:
Http.apply(request OK as.String)
好的,apply
里面发生了什么?似乎正在 request
上调用名为 OK
的方法。但是查看 API Docs,您可能会注意到类型 Req
没有这样的方法 OK
。然而,有一种叫做RequestHandlerTupleBuilder
的class,它确实有这样的方法。并且在dispatch
包中定义了一个隐式转换:
implicit def implyRequestHandlerTuple(builder: Req) =
new RequestHandlerTupleBuilder(builder)
这里发生的事情是,当您调用 request OK
时,编译器发现 request
没有 OK
方法。因此,它然后寻找可能的隐式方法,这些方法接受 Req
作为参数,并且 return 类型确实具有这样的方法。上面的方法是它找到的隐式,所以 Req
被隐式转换为 RequestHandlerTupleBuilder
.
现在让我们看看OK
的签名:
def OK [T](f: Response => T): (Request, OkFunctionHandler[T])
它接受一个函数作为参数。特别是,一个函数接受 Response
作为参数,并且 return 是其他类型 T
。在本例中,这样的函数是 as.String
,类型为 Response => String
。 OK
然后 return 一个 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
只有一个参数被传递,它只是使用一种无指向的方式来调用内部的其他方法。
我是一名Java工程师,最近一直在慢慢学习Scala。我遇到了一些使用 Dispatch 发出简单 GET 请求的示例代码:
val request = url("http://somesite.com")
val result = Http( request OK as.String)
问题是...我不太明白这里发生了什么。首先,Http是class吗?还是一种方法?其次,传递给它的参数是怎么回事?我想也许我们传递了三个参数,Scala 允许我们省略逗号。但是当我尝试添加逗号时,我遇到了编译错误,所以这不对。
我相信这对精通 Scala 的人来说是有意义的,但我还没有做到这一点,它阻碍了我。我试过在线查找文档,但没有找到任何帮助。
这是一个(痛苦的)显式版本,去掉了所有语法糖:
import dispatch.{ Defaults, Http, Req, as, implyRequestHandlerTuple, url }
import scala.concurrent.Future
val request: Req = url.apply("http://somesite.com")
val result: Future[String] =
Http.apply(
implyRequestHandlerTuple(request).OK[String](as.String)
)(Defaults.executor)
url
is a singleton object with an apply
method that returns an instance of the Req
case class. Http
is also a singleton object, and it also has an apply
method. Http
's apply
takes two parameter lists—the first taking a single Req
parameter, and the second taking an execution context (which you can think of as Scala's version of Java's Executor
).
implyRequestHandlerTuple
是一种 隐式 方法。 Req
没有 OK
方法,但编译器知道 RequestHandlerTupleBuilder
class 有(并且它采用适当的参数——在本例中是来自 Response
到某种类型),因此在原始版本中它会自动应用此方法从 Req
.
最后,as
是一个包含 String
单例对象的包。这个对象扩展了 Response => String
(这是 [=29= 的更多语法糖)。我们的 OK
方法正在寻找一个采用 Response
的函数,所以我们在那里很好。
最后你得到了 Future[String]
。有很多other places阅读关于期货,所以我不会在这里详细介绍,但简而言之,这个值可以是不满意的(即你还在等待结果),或者对失败感到满意(在网络错误等情况下),或成功满足(在这种情况下它将包含响应主体)。
url
是(本质上)一种 return 是 Req
对象的方法。所以 request
的类型是 Req
.
Http
是一个带有伴生对象的 class,它有一些 apply
方法的重载。所以当你看到:
Http(request OK as.String)
它实际上是语法糖:
Http.apply(request OK as.String)
好的,apply
里面发生了什么?似乎正在 request
上调用名为 OK
的方法。但是查看 API Docs,您可能会注意到类型 Req
没有这样的方法 OK
。然而,有一种叫做RequestHandlerTupleBuilder
的class,它确实有这样的方法。并且在dispatch
包中定义了一个隐式转换:
implicit def implyRequestHandlerTuple(builder: Req) =
new RequestHandlerTupleBuilder(builder)
这里发生的事情是,当您调用 request OK
时,编译器发现 request
没有 OK
方法。因此,它然后寻找可能的隐式方法,这些方法接受 Req
作为参数,并且 return 类型确实具有这样的方法。上面的方法是它找到的隐式,所以 Req
被隐式转换为 RequestHandlerTupleBuilder
.
现在让我们看看OK
的签名:
def OK [T](f: Response => T): (Request, OkFunctionHandler[T])
它接受一个函数作为参数。特别是,一个函数接受 Response
作为参数,并且 return 是其他类型 T
。在本例中,这样的函数是 as.String
,类型为 Response => String
。 OK
然后 return 一个 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
只有一个参数被传递,它只是使用一种无指向的方式来调用内部的其他方法。