Tôi không hiểu tại sao các tác giả cho rằng Mã 9.1 từ "Lập trình trong Scala" sử dụng đóng. Trong chương 9, họ cho thấy làm thế nào để cấu trúc lại mã vào nhiều hình thức ít bị trùng lặp, từ mã gốc này:Câu hỏi về đóng cửa Scala (Từ "Lập trình trong Scala")
object FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
def filesEnding(query: String) =
for (file <- filesHere; if file.getName.endsWith(query))
yield file
def filesContaining(query: String) =
for (file <- filesHere; if file.getName.contains(query))
yield file
def filesRegex(query: String) =
for (file <- filesHere; if file.getName.matches(query))
yield file
}
Đối với phiên bản thứ hai:
object FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
def filesMatching(query: String,
matcher: (String, String) => Boolean) = {
for (file <- filesHere; if matcher(file.getName, query))
yield file
}
def filesEnding(query: String) =
filesMatching(query, _.endsWith(_))
def filesContaining(query: String) =
filesMatching(query, _.contains(_))
def filesRegex(query: String) =
filesMatching(query, _.matches(_))
}
Mà họ nói rằng không có sử dụng đóng cửa đây. Bây giờ tôi hiểu cho đến thời điểm này. Tuy nhiên họ giới thiệu việc sử dụng đóng cửa Refactor thậm chí một số chi tiết, thể hiện trong Liệt kê 9.1:
object FileMatcher {
private def filesHere = (new java.io.File(".")).listFiles
private def filesMatching(matcher: String => Boolean) =
for (file <- filesHere; if matcher(file.getName))
yield file
def filesEnding(query: String) =
filesMatching(_.endsWith(query))
def filesContaining(query: String) =
filesMatching(_.contains(query))
def filesRegex(query: String) =
filesMatching(_.matches(query))
}
Bây giờ họ nói rằng truy vấn là một biến miễn phí nhưng tôi không thực sự hiểu tại sao họ lại nói như vậy? Vì "" truy vấn "" dường như được truyền từ phương thức hàng đầu xuống đến hàm kết hợp chuỗi một cách rõ ràng.
Tôi hiểu chính xác rằng vì phương pháp "đối sánh" thu thập biến "truy vấn" do đó nó sử dụng đóng. – Ekkmanz
Có, trong mã này "def filesEnding (truy vấn: String) = filesMatching (_. EndsWith (truy vấn))" có một lambda "_.endsWith (truy vấn)" mà khi desugared một chút trông giống như "{x => x .endsWith (truy vấn)} ". Trong ký hiệu schemey sẽ giống như "(lambda (x) (endwith x query))". Như bạn có thể thấy, trong truy vấn "lambda" là một biến miễn phí. Nó không bị ràng buộc như một đối số cũng như không cho phép trong lambda, vì vậy khi truy vấn được tạo thành được truy vấn được lấy từ môi trường có chứa, ví dụ: invocations của các phương thức như "filesEnding". –