2015-01-26 29 views
11

Tôi là kỹ sư Java, người đang dần dần học Scala. Tôi đã đi qua một số mã mẫu bằng cách sử dụng Công văn để thực hiện yêu cầu GET đơn giản:Ví dụ về Scala dispatch

val request = url("http://somesite.com") 
val result = Http(request OK as.String) 

Vấn đề là ... Tôi không hiểu chuyện gì đang xảy ra ở đây. Đầu tiên, là một lớp học Http? hoặc một phương pháp? Thứ hai, những gì đang xảy ra với các thông số được truyền cho nó? Tôi nghĩ có lẽ chúng tôi đã vượt qua ba lý lẽ, với Scala cho phép chúng tôi bỏ qua dấu phẩy. Nhưng khi tôi thử thêm dấu phẩy, tôi nhận được một lỗi biên dịch, do đó không thể đúng.

Tôi chắc chắn điều này có ý nghĩa với một người thông thạo Scala, nhưng tôi chưa có mặt ở đó và nó đang giữ tôi. Tôi đã thử tìm kiếm tài liệu trực tuyến, nhưng không tìm thấy gì hữu ích.

+0

Ồ, xin lỗi. Đó là trong Scala dành cho các nhà phát triển Java, mà tôi đang đọc qua, nhưng tôi cũng đã thấy các ví dụ tương tự trực tuyến; ví dụ. http://stackoverflow.com/questions/21103553/scala-dispatch-simple-get-request và thậm chí trên trang web Công văn: http://dispatch.databinder.net/Dispatch.html –

Trả lời

26

Dưới đây là một (đau đớn) phiên bản rõ ràng với tất cả các đường cú pháp đưa ra:

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 là một đối tượng singleton với một phương pháp apply trả về một thể hiện của lớp Req hợp cụ thể. Http cũng là một đối tượng đơn lẻ, và nó cũng có phương thức apply. Http 's apply có hai danh sách tham số — đầu tiên lấy một tham số Req duy nhất và tham số thứ hai lấy ngữ cảnh thực thi (mà bạn có thể coi là phiên bản Java 1.của Scala).

implyRequestHandlerTuple là phương pháp ẩn ẩn. Req không có phương thức OK, nhưng trình biên dịch biết rằng lớp RequestHandlerTupleBuilder thực hiện (và phải có đối số thích hợp — trong trường hợp này là hàm từ Response đối với một số loại), vì vậy trong phiên bản gốc nó sẽ tự động áp dụng phương pháp này thực hiện chuyển đổi từ Req.

Cuối cùng, as là gói chứa đối tượng singleton String. Đối tượng này kéo dài Response => String (đó là đường cú pháp hơn cho Function1[Response, String]. Phương pháp OK chúng tôi đang tìm kiếm một chức năng tham gia một Response, vì vậy chúng tôi tốt ở đó.

Cuối cùng bạn đã có một Future[String]. Có rất nhiều other places để đọc về tương lai, vì vậy tôi sẽ không đi vào chi tiết ở đây, nhưng trong ngắn hạn giá trị này có thể là không hài lòng (tức là bạn vẫn đang chờ kết quả), hoặc hài lòng với một thất bại (trong trường hợp lỗi mạng, vv .), hoặc đã thỏa mãn thành công (trong trường hợp này nó sẽ chứa nội dung phản hồi)

+5

Có thể bạn đã bắt đầu 12 giây trước đó, hoặc có thể bạn biết những từ cần loại bỏ. Đô la giáo dục nhân văn của bạn tại nơi làm việc. Tôi sẽ để con gái tôi đọc câu trả lời này trước khi cô ấy bắt đầu vào bản báo cáo tiếp theo của mình. Tôi thấy bạn sử dụng các từ chuyển tiếp được đề xuất bởi bà Roberts: "cuối cùng", "cuối cùng". Kiểm tra cộng! –

8

url là (về cơ bản) một phương thức trả về đối tượng Req.Vì vậy, request có loại Req.

Http là một lớp có đối tượng đồng hành có quá tải một số phương thức apply. Vì vậy, khi bạn nhìn thấy:

Http(request OK as.String) 

Đó là đường thực sự cú pháp cho:

Http.apply(request OK as.String) 

Ok, vì vậy những gì đang xảy ra bên trong apply? Dường như phương thức có tên là OK đang được gọi trên request. Nhưng nhìn qua API Docs, bạn có thể nhận thấy không có phương pháp như vậy OK cho loại Req.Tuy nhiên, có một lớp được gọi là RequestHandlerTupleBuilder, có một phương thức như vậy. Và có một chuyển đổi ngầm định nghĩa trong gói dispatch:

implicit def implyRequestHandlerTuple(builder: Req) = 
    new RequestHandlerTupleBuilder(builder) 

gì đang xảy ra ở đây là khi bạn gọi request OK, trình biên dịch thấy rằng request không có một phương pháp OK. Vì vậy, nó sẽ tìm kiếm các phương thức tiềm ẩn có thể chấp nhận Req như một tham số và các kiểu trả về để thực hiện một phương thức như vậy. Phương pháp trên là ngầm nó tìm thấy, do đó, Req được chuyển đổi hoàn toàn thành RequestHandlerTupleBuilder.

Bây giờ chúng ta hãy nhìn vào chữ ký của OK:

def OK [T](f: Response => T): (Request, OkFunctionHandler[T]) 

Nó chấp nhận một chức năng như một tham số. Cụ thể, một hàm chấp nhận thông số Response và trả về một số loại khác T. Trong trường hợp này, một hàm như vậy là as.String có loại Response => String. OK sau đó sẽ trả lại một Request tupled với một OkFunctionHandler[T].

này nói với tôi rằng sự quá tải của apply chúng tôi đang gọi điện thoại này là một:

def apply[T](pair: (Request, AsyncHandler[T])): Future[T] 

(OkFunctionHandler kéo dài AsyncHandler)

Nhìn nó tất cả trong một phong cách java giống như hơi hơn và với loại chú thích, bạn có:

val request: Req = url("http://somesite.com") 
val result: Future[String] = Http.apply(request.OK(as.String)) 

Chỉ sử dụng các cuộc gọi rõ ràng, nó trông giống như sau:

val result: Future[String] = 
    Http.apply(implyRequestHandlerTuple(request).OK(as.String)) 

Tóm lại, chỉ có một thông số được chuyển đến Http.apply, nó chỉ sử dụng kiểu không có điểm để gọi các phương thức khác bên trong.

+0

Wow, tôi nghĩ rằng tôi đánh bại bạn bằng 12 giây. Tôi cũng thích câu trả lời của bạn, nhưng bạn có thể rõ ràng hơn về thực tế là 'request OK as.String' được phân tích thành' request.OK (as.String) '. –

+0

@TravisBrown Khó rõ ràng hơn là giải thích ở dưới cùng. Nhưng là 'url' về cơ bản là một phương pháp? Đó sẽ là ok nếu ScalaDoc có một "trường hợp sử dụng", nơi bạn bấm vào một phương thức 'url' và nó sẽ đưa bạn đến đối tượng-với-một-áp dụng. Tôi hy vọng những người ScalaDoc không đọc nó. –

+0

Tôi lóe lên trên 'url', bởi vì OP không thực sự hỏi về nó. Bây giờ tôi có một số đo không chính thức về số lượng của tôi để thực hiện một @TravisBrown. –