2009-08-16 31 views
9

Tìm thấy đoạn mã sau đây trên trang Closure trên wikipediaScala đóng cửa trên wikipedia

//# Return a list of all books with at least 'threshold' copies sold. 
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold) 
//# or 
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold) 

Đúng tôi nếu tôi là sai, nhưng đây không phải là đóng cửa? Nó là một hàm theo nghĩa đen, một hàm bất kỳ, một hàm lambda, nhưng không phải là một sự kết thúc?

+0

Tại sao ngưỡng là một thuật ngữ đóng? Đó là một biến cục bộ được hàm bắt giữ khi nó được chuyển tới phương thức lọc, không? – skaffman

+0

bạn nói đúng. ngưỡng không phải là một thuật ngữ khép kín, biến miễn phí của nó và việc đóng cửa là một thuật ngữ mở. – Schildmeijer

Trả lời

14

Vâng ... nếu bạn muốn là kỹ thuật, đây là một hàm được dịch khi chạy vào thời điểm đóng, đóng các thuật ngữ mở (ràng buộc chúng thành một val/var trong phạm vi của hàm theo nghĩa đen). Ngoài ra, trong ngữ cảnh của hàm này theo nghĩa đen (_.sales >= threshold), threshold là một biến số miễn phí, vì chính hàm theo nghĩa đen không mang ý nghĩa gì. Chính nó, _.sales >= thresholdthuật ngữ mở Khi chạy, nó được liên kết với biến cục bộ của hàm, mỗi lần hàm được gọi.

Đi chức năng này ví dụ, tạo ra đóng cửa:

def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc 

Khi chạy, các mã sau đây tạo ra 3 đóng cửa. Nó cũng thú vị để lưu ý rằng b và c không phải là cùng một đóng cửa (b == c cho false).

val a = makeIncrementer(10) 
val b = makeIncrementer(20) 
val c = makeIncrementer(20) 

Tôi vẫn nghĩ rằng ví dụ được đưa ra trên wikipedia là một ví dụ tốt, mặc dù không hoàn toàn bao gồm toàn bộ câu chuyện. Nó khá khó khăn cho một ví dụ về đóng cửa thực tế theo định nghĩa chặt chẽ nhất mà không thực sự là một kết xuất bộ nhớ của một chương trình đang chạy. Nó giống với quan hệ lớp-đối tượng. Bạn thường đưa ra một ví dụ về một đối tượng bằng cách định nghĩa một số class Foo { ... và sau đó khởi tạo nó với val f = new Foo, nói rằng f là đối tượng.

-- Flaviu Cipcigan

Ghi chú:

  • tham khảo: Lập trình tại Scala, Martin Odersky, Lex Spoon, Bill Venners
  • Mã biên soạn với Scala phiên bản 2.7.5.final chạy trên Java 1.6.0_14 .
+0

câu trả lời tuyệt vời +1 –

1

Tôi không hoàn toàn chắc chắn, nhưng tôi nghĩ bạn nói đúng. Không phải là một đóng cửa yêu cầu nhà nước (tôi đoán biến miễn phí ...)?

Hoặc có thể bookList là biến miễn phí?

+0

"Hệ thống suy luận kiểu của Scala tự động nhận ra đối số để lọc thành một hàm lấy một cuốn sách và trả về một giá trị Boolean và biến nó thành một đóng". – Schildmeijer

0

Theo như tôi hiểu, đây là một kết thúc có chứa một tham số chính thức, ngưỡng biến và bối cảnh, Booklist, từ phạm vi kèm theo. Vì vậy, giá trị trả về (List [Any]) của hàm có thể thay đổi khi áp dụng hàm biến vị ngữ bộ lọc. Nó thay đổi dựa trên các yếu tố của biến List (bookList) từ ngữ cảnh.