Cậu bé, đó là một cách tinh tế, nhưng theo như tôi có thể nói nó theo sau Scala spec hoàn toàn. Tôi sẽ trích dẫn từ phiên bản 2.9 của spec.
Ví dụ đầu tiên của bạn: như bạn một cách đúng đắn nói, bạn đang nhìn thấy sự bành trướng eta qua một trường hợp đặc biệt của một Value Method (§6.7):
The expression e _ is well-formed if e is of method type or if e is a call-by-name parameter. If e is a method with parameters, e _ represents e converted to a function type by eta expansion.
Thuật toán để mở rộng eta được đưa ra trong § 6.26.5 mà bạn có thể làm theo để cung cấp cho việc thay đổi sau đây cho biểu new Foo().x1 _
:
{
val x1 = new Foo();
(y1: Int) => x1.(y1);
}
Điều này ngụ ý rằng khi mở rộng eta đang được sử dụng, tất cả các tiểu biểu thức được đánh giá tại điểm mà c đảo ngược diễn ra (nếu tôi đã hiểu ý nghĩa của cụm từ "biểu thức phụ tối đa" một cách chính xác) và biểu thức cuối cùng là tạo ra một hàm ẩn danh.
Trong ví dụ thứ hai của bạn, những ngoặc thêm có nghĩa là trình biên dịch sẽ xem xét §6.23 (đặc biệt là "giữ chỗ Cú pháp cho hàm Anonymous) và tạo ra một chức năng ẩn danh trực tiếp.
An expression (of syntactic category Expr) may contain embedded underscore symbols _ at places where identifiers are legal. Such an expression represents an anonymous function where subsequent occurrences of underscores denote successive parameters.
Trong trường hợp đó , và sau các thuật toán trong phần đó, biểu hiện của bạn kết thúc lên được điều này:
(x1: Int) => new Foo().foo(x1)
sự khác biệt là tinh tế và, như đã giải thích rất tốt bởi @Antoras, chỉ thực sự cho thấy sự hiện diện của mã tác dụng phụ.
Lưu ý rằng có một sửa lỗi trong trường hợp liên quan đến các khối mã theo từng tên (xem, ví dụ: this question, this bug và this bug).
Postscript: Trong cả hai trường hợp, chức năng ẩn danh (x1:Int) => toto
được mở rộng để
new scala.Function1[Int, Int] {
def apply(x1: Int): Int = toto
}
Câu hỏi này đã có một câu trả lời, nhưng tôi không thể nhìn thấy nó nữa. Có ai đó xóa nó không? –