Scala调度示例
我是一名Java工程师,最近一直在慢慢学习Scala。我遇到了一些使用Dispatch发出简单GET请求的示例代码:Scala调度示例,scala,Scala,我是一名Java工程师,最近一直在慢慢学习Scala。我遇到了一些使用Dispatch发出简单GET请求的示例代码: val request = url("http://somesite.com") val result = Http( request OK as.String) 问题是。。。我不太明白这里发生了什么。首先,Http是一个类吗?还是一种方法?其次,传递给它的参数是怎么回事?我想也许我们传递了三个参数,Scala允许我们省略逗号。但是当我尝试添加逗号时,我得到了一个编译错误,所以
val request = url("http://somesite.com")
val result = Http( request OK as.String)
问题是。。。我不太明白这里发生了什么。首先,Http是一个类吗?还是一种方法?其次,传递给它的参数是怎么回事?我想也许我们传递了三个参数,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)
是一个带有apply
方法的单例对象,该方法返回Req
case类的实例。也是一个单例对象,它还有一个apply
方法Http
的apply
采用两个参数列表,第一个采用单个Req
参数,第二个采用执行上下文(您可以将其视为Scala版本的Java)
是一种隐式方法Req
没有OK
方法,但编译器知道RequestHandlerTupleBuilder
类有(在本例中,它采用适当的参数将函数从Response
转换为某种类型),因此,在原始版本中,它会自动应用此方法从Req
进行转换
最后,as
是一个包含单例对象的包。这个对象扩展了Response=>String
(这是Function1[Response,String]
的语法糖。我们的OK
方法是寻找一个接受响应的函数,所以我们在这方面做得很好
最后你得到了一个未来[String]
。关于未来有很多值得阅读的内容,所以我在这里不详细介绍,但简而言之,这个值可能不令人满意(即,你仍在等待结果),或者对失败感到满意(在网络出错的情况下,等等),或者成功地感到满意(在这种情况下,它将包含响应主体)。url
是(本质上)返回Req
对象的方法。因此请求
具有类型Req
Http
是一个类,它有一个伴随对象,该对象有一些apply
方法的重载。因此,当您看到:
Http(request OK as.String)
它实际上是语法糖:
Http.apply(request OK as.String)
好的,那么apply
内部发生了什么呢?看起来好像在request
上调用了一个名为Ok
的方法。但是,通过查看,您可能会注意到,对于类型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])
它接受一个函数作为参数。特别是,一个函数接受一个响应
作为参数,并返回一些其他类型的T
。在这种情况下,这样一个函数是as.String
,它的类型为响应=>String
确定
,然后将返回一个请求
并用参数进行元组化ActionHandler[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,我正在通读,但我在网上也看到过类似的例子;例如,甚至在调度网站上:哇,我想我比你快了12秒。我喜欢e您的答案也是一样,但是您可以更清楚地知道,request OK as.String
被解析为request.OK(as.String)
@TravisBrown很难比下面的解释更清楚。但是url
本质上是一种方法吗?如果ScalaDoc有一个“用例”,那就可以了你点击一个方法url
,它会带你到一个应用程序的对象。我希望ScalaDoc的人没有读到这篇文章。我对url
感到茫然,因为OP并不是真的在问它。现在我有一个非官方的测量,我需要多少人来做一个@TravisBrown。有一个+1来平衡一下差距。:)也许你早12秒就开始了,或者也许你知道该省掉什么词。你的人文教育经费在发挥作用。我打算让我女儿在开始下一次读书报告之前读一下这个答案。我看到你使用了罗伯茨女士推荐的过渡词:“最后”、“最后”。检查加号!