_ (gạch dưới) là một từ khóa dành riêng


92

Tôi vừa thay thế strong biểu thức lambda sau bằng _:

s -> Integer.parseInt(s)

Trình biên dịch Eclipse cho biết:

'_' không nên được sử dụng làm định danh, vì nó là từ khóa dành riêng từ nguồn cấp 1.8 trở đi.

Tôi không tìm thấy bất kỳ giải thích nào trong JLS §3.9 Cấu trúc Lexical / Từ khóa.

Câu trả lời:


83

Nơi cần xem xét là JLS §15.27.1. Tham số Lambda

Đây là lỗi thời gian biên dịch nếu một tham số lambda có tên _ (nghĩa là một ký tự gạch dưới).

Việc sử dụng tên biến _ trong bất kỳ ngữ cảnh nào đều không được khuyến khích. Các phiên bản tương lai của ngôn ngữ lập trình Java có thể đặt tên này làm từ khóa và / hoặc đặt cho nó ngữ nghĩa đặc biệt.

Vì vậy, thông báo Eclipse gây hiểu lầm, đặc biệt khi cùng một thông báo được sử dụng cho cả hai trường hợp, khi lỗi được tạo ra cho một tham số lambda hoặc khi một cảnh báo được tạo ra cho bất kỳ số _nhận dạng nào khác .


21
Lưu ý rằng kể từ Java 9, _sẽ không được phép sử dụng dưới dạng bất kỳ tên định danh hợp pháp nào và không chỉ là tên tham số lambda. Điều này thực sự đã được khắc phục trong bản dựng 43: bug.openjdk.java.net/browse/JDK-8061549
Jean-François Savard

3
@lscoughlin: Không phải là "Các phiên bản tương lai của ngôn ngữ lập trình Java có thể đặt tên này như một từ khóa và / hoặc đặt cho nó ngữ nghĩa đặc biệt" là đủ? Tốt, hãy thay thế “có thể đặt trước” bằng “sẽ sử dụng”, và bạn sẽ nhận được bức tranh. Có thể tài liệu tham khảo thư này giúp ích…
Holger

5
Cái này là cái gì? Java phá vỡ khả năng tương thích ngược?
Arturo Torres Sánchez

8
@Arturo Torres Sánchez: không có gì mới. Đã có lúc enumassertlà số nhận dạng hợp pháp…
Holger

11
@Holger thực sự có rất nhiều ngôn ngữ sử dụng dấu gạch dưới làm trình giữ chỗ tên (Scala, Clojure, F #, SML, Erlang, chỉ để đặt tên cho một vài ngôn ngữ). Tôi tin rằng đó là một mô hình đã có từ những năm 90 hoặc 80, vì vậy việc không tuân theo nó là một điều kỳ lạ.
om-nom-nom

23

Đó là Giai đoạn 2 của JEP 302 , sẽ thêm dấu gạch dưới làm ký tự đặc biệt để biểu thị các tham số không sử dụng trong biểu thức lambda.

Xử lý dấu gạch dưới

Trong nhiều ngôn ngữ, người ta thường sử dụng dấu gạch dưới ( _) để biểu thị một tham số lambda không được đặt tên (và tương tự cho các tham số phương thức và ngoại lệ):

BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);

Điều này cho phép kiểm tra tĩnh mạnh mẽ hơn đối với các đối số không sử dụng và cũng cho phép nhiều đối số được đánh dấu là không sử dụng. Tuy nhiên, vì dấu gạch dưới là một mã định danh hợp lệ của Java 8, nên khả năng tương thích yêu cầu chúng ta thực hiện một con đường gián tiếp hơn để đến nơi dấu gạch dưới có thể phục vụ vai trò này trong Java. Giai đoạn 1 là cấm dấu gạch dưới làm tên tham số chính thức lambda trong Java 8 (điều này không có hậu quả tương thích, vì lambdas không tồn tại trước đó) và cảnh báo đã được đưa ra vì sử dụng dấu gạch dưới làm số nhận dạng ở những nơi khác. Giai đoạn 2 đến trong Java 9, khi cảnh báo này trở thành lỗi. Bây giờ chúng tôi có thể hoàn thành việc khôi phục theo kế hoạch của dấu gạch dưới để chỉ ra một tham số chính thức, phương thức hoặc lambda chưa được sử dụng.


1
Cách sử dụng này được Brian Goetz thảo luận trong bài nói chuyện Devoxx của anh ấy vào năm 2017-11 về Dự án Amber .
Basil Bourque,

OK, nhưng đâu là lựa chọn thay thế để biểu thị các tham số không sử dụng trong J8? Điều đó là không thể ở tất cả?
Manuel

1
Chúng tôi hiện đang sử dụng $cho mục đích này.
aventurin

Bây giờ tôi đang sử dụng Java 14 và tôi vẫn không thể sử dụng dấu gạch dưới làm tham số lambda không tên. Bất cứ điều gì mà JCP đặt ra để đạt được, có vẻ như họ đã đạt được điều ngược lại.
Frans

@Frans Lưu ý rằng JEP (tính đến ngày nay) chỉ ở giai đoạn ứng viên. Nó vẫn chưa được hoàn thành. Để biết thêm chi tiết về quy trình JEP,
Alexandre de Champeaux

5

Các thay đổi về ngôn ngữ Java cho Java SE 9 https://docs.oracle.com/javase/9/language/toc.htm#JSLAN-GUID-16A5183A-DC0D-4A96-B9D8-AAC9671222DD

Từ Java 9, ký tự _ không thể được sử dụng làm định danh nữa, không chỉ trong ngữ cảnh lambda

Ký tự gạch dưới không phải là tên hợp pháp.

Nếu bạn sử dụng ký tự gạch dưới ("_") làm định danh, thì mã nguồn của bạn không thể được biên dịch nữa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.