2013-09-25 40 views
18

Tôi đang gặp khó khăn khi tìm câu trả lời cụ thể cho những gì tôi biết là điều gì đó tầm thường. Tôi muốn hiểu cách khối hoạt động trong Scala. Tôi đến từ một nền java/ruby ​​và có vẻ như scala có một cách hoàn toàn khác với việc sử dụng các khối.Tìm hiểu Khối Scala

Mã sau đây là từ Play! Framework website. Tôi muốn hiểu những gì Hành động là ngữ nghĩa. Nó là một đối tượng hoặc một chức năng chấp nhận một khối, hoặc có lẽ không.

object Application extends Controller { 

    def index = Action { 
    Ok(views.html.index("Your new application is ready.")) 
    } 

} 

Nếu nó là một chức năng, có lẽ đó là đường cú pháp sau (trong trường hợp này như thế nào scala vượt qua xung quanh khối đằng sau hậu trường):

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
    }) 

Hoặc là nó một số cú pháp scala tôi m không biết.

Mọi tham chiếu đến mã nguồn Scala sẽ giúp tôi hiểu cách thức hoạt động của cảnh hậu trường.

Trả lời

21

Bạn nên suy nghĩ về các khối scala như các lớp ẩn danh java (ví dụ như hàm Guava) chứ không phải là khối ruby. Nói thực ra, nếu bạn dịch ngược đang scala bạn sẽ thấy nhiều hơn hoặc ít hơn cùng mã (taken from Guava examples):

Function<String, Integer> lengthFunction = new Function<String, Integer>() { 
    public Integer apply(String string) { 
    return string.length(); 
    } 
}; 

Sự khác biệt là scala cung cấp rất nhiều đường cú pháp và cho phép bạn viết trên mã như:

val lengthFunction = { string: String => string.length } 

đối với một ví dụ hành động cụ thể:

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
    }) 

đây hành động có khả năng đối tượng với phương pháp áp dụng. Đường scala khác: ngôn ngữ cho phép bạn viết Foo(bar) và có nghĩa là Foo.apply(bar).Tiếp theo, you can drop round braces when your call isn't ambiguous, vì vậy có, nó thực sự là một phương pháp mà đã được gọi như:

def index = Action({ 
    Ok(views.html.index("Your new application is ready.")) 
}) 

Và có một cái gì đó như thế này như một chữ ký:

object Action { 
    def apply(block: => Result) = ??? 
} 

Như đã nói bởi @yan, nó là scala cách để nói hey, tôi là một chức năng chấp nhận một chức năng mà tạo ra quả

khử đường gọi sẽ trông giống như

def index = Action.apply(new AbstractFunction[Result] { 
     def apply() = Ok.apply(views.html.index.apply("...")) 
}) 
8

Có một vài điều đang diễn ra tại đây. Action là một đối tượng triển khai phương thức apply(), phương thức được gọi khi bạn xử lý đối tượng dưới dạng hàm. Có một vài số apply()implementations. Việc triển khai đầu tiên sử dụng tham số theo tên. Scala hỗ trợ một khái niệm được gọi là 'tham số bằng tên', giống như thông số bình thường, ngoại trừ chúng chỉ được đánh giá khi mã tham chiếu chúng được thực hiện. Chúng giúp tạo cấu trúc xuất hiện giống như chúng là một phần của ngôn ngữ mà không cần sử dụng macro. Trong trường hợp này, khối xung quanh Ok(..) chỉ là một khối thông thường của các câu lệnh, với giá trị cuối cùng được sử dụng làm giá trị của khối. Ví dụ bạn cung cấp sẽ hoạt động tốt mà không có dấu ngoặc ôm. Về cơ bản, bạn chỉ cần chuyển kết quả của phương thức apply của Ok tới phương thức apply của Action.

Phiên bản thứ hai của apply() thực sự thực hiện một chức năng ẩn danh đầy đủ để ánh xạ Yêu cầu đến một kết quả. Trong trường hợp này, bạn có thể chuyển một hàm ẩn danh (hoặc được đặt tên).

+0

Cảm ơn bạn đã trả lời. Vì vậy, từ những gì tôi đang thu thập, đây là đường cú pháp cho Action.apply(). Loại bỏ đường, toàn bộ câu nói sẽ như thế nào? – b1nd

+0

Câu lệnh mà bạn có về cơ bản là 'Action.apply (Ok.apply (views.html.index (" Ứng dụng mới của bạn đã sẵn sàng. ")))'. Nếu bạn nhìn vào định nghĩa 'apply()' trong URL mà tôi đã cung cấp, bạn sẽ thấy một mũi tên trước kiểu tham số. Điều đó chỉ đánh dấu nó là tham số 'by-name', được mô tả ở trên. (Ngoài ra, nó không phải ngẫu nhiên mà cú pháp cho by-name trông giống như một hàm ẩn danh không có đối số) – yan

+0

Liên kết để chơi doc bị hỏng bằng cách này. Đôi khi, SO parser messes up liên kết có chứa ký hiệu đô la. –