2015-02-01 17 views
5

Gần đây tôi đã xem một số presentation từ EclipseCon 2014, ở trang 5 họ nói "Biểu thức Lambda cho phép bạn xem mã dưới dạng dữ liệu"."Mã dưới dạng dữ liệu" có nghĩa là gì?

Tôi cũng đã xem qua ví dụ này đang

button.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent event) { 
     System.out.println("button clicked"); 
    } 
}); 

từ "Java 8 Lambdas: Pragmatic chức năng lập trình" bởi Richard Warburton nơi ông nói

"Đây thực sự là một ví dụ của việc sử dụng mã như dữ liệu — chúng tôi đang cung cấp nút một đối tượng đại diện cho một hành động. "

Mã số là dữ liệu có nghĩa là liên quan đến biểu thức Lambda và/hoặc lớp bên trong vô danh?

+0

Tôi đoán rằng nó đề cập đến việc truyền xung quanh một phương thức như một giá trị, mà lambdas mang đến cho ảo giác về việc làm. Các giá trị được xem là dữ liệu và "mã" có thể đề cập đến khối mã là phương thức –

+0

Trông giống như bất kỳ ngôn ngữ chức năng nào xử lý các hàm như _prime class citizens_ (khái niệm để cung cấp hàm như đầu vào cho hàm khác). Ví dụ này với tôi trông khá lộn xộn, các ngôn ngữ khác có chức năng hoặc lai-chức năng làm một công việc tốt hơn với cú pháp, hãy kiểm tra Scala ví dụ (mà vẫn còn dựa trên JVM). – Marcs

+0

"Mã dưới dạng dữ liệu" là khẩu hiệu không có nghĩa là bất kỳ điều gì bạn chưa biết. – immibis

Trả lời

1

Ý tưởng về "mã dưới dạng dữ liệu" có liên quan chặt chẽ với khái niệm ngôn ngữ lập trình có chức năng hạng nhất. Xem Wikipedia article về chủ đề này. Trong số này other answer Tôi nói về việc liệu Java có các hàm hạng nhất hay không, nhưng bài viết đó cũng thảo luận về một số vấn đề khác.

Định nghĩa từ các bài viết Wikipedia (mà trích dẫn Abelson & Sussman, Cấu trúc và Giải thích chương trình máy tính, phần 1.3) đặc biệt đề cập đến các đặc điểm sau của chức năng mà làm cho họ "hạng nhất":

  • có thể được thông qua như là đối số cho các chức năng khác
  • thể được trả lại như các giá trị từ các chức năng khác
  • thể được gán cho các biến
  • có thể được lưu trữ trong cấu trúc dữ liệu

Đây là tất cả những gì bạn làm với dữ liệu. Nếu bạn có thể làm những điều tương tự với các hàm, thì điều đó giống như xử lý "mã dưới dạng dữ liệu".

Nếu bạn xem xét chặt chẽ cách lambdas được thêm vào ngôn ngữ lập trình Java, bạn sẽ thấy rằng lambda thực sự được chuyển đổi thành thể hiện của giao diện chức năng. Như vậy, nó là một thể hiện của một số đối tượng, và do đó một hậu duệ của lớp Object và giống như tất cả các đối tượng trong Java, nó có các phương thức equals(), hashCode(), getClass() vv và tham chiếu có thể được so sánh với ==, v.v. Tuy nhiên, bạn hoàn toàn không được khuyến khích dựa vào bất kỳ điều nào trong số này. Xem số other answer của tôi để thảo luận thêm. Trong thực tế, khi bạn sử dụng lambdas trong Java, nó thực sự cảm thấy như bạn đang truyền mã như một đối số, hoặc gán nó cho một biến. Ví dụ:

list.replaceAll(x -> doSomething(x)); 

Predicate<String> pred = s -> s.length() > 5; 

Bạn thực sự không nghĩ đến thực tế rằng, dưới bìa, lambdas là đối tượng là trường hợp giao diện chức năng.

5

Khi bạn chuyển chức năng làm đối số cho phương pháp khác, chẳng hạn như hành động sẽ được thực hiện khi ai đó nhấp vào nút như mã mẫu của bạn.

Biểu thức Lambda cho phép bạn thực hiện việc này, để xử lý chức năng làm đối số phương thức = code as data.

Xem oracle link để biết thêm thông tin và ví dụ về mã lambda.

1

Nó có nghĩa là bạn chương trình mã bạn viết cũng là một dữ liệu có thể được thông qua như là một cuộc tranh cãi để method khác và thao túng bởi một chương trình.

1

Trong thời kỳ hoàng kim của Java, không có mô hình thuận tiện để chuyển chức năng từ người gọi đến người nhận. Bạn phải hack cùng một lớp với một số phương thức (thường là thông qua mẫu thiết kế "Command") và sau đó chuyển nó cho người nhận.

Java 8 Lambdas đã dịch chuyển mô hình bằng cách giới thiệu các biểu thức Lambda. Quên về cách chúng được biểu diễn cho thời gian chạy, Lambdas xuất hiện với nhà phát triển như là mã thuần túy có thể được truyền cho các phương thức. Mã dưới dạng dữ liệu!

Sự thay đổi mô hình này đã mở đường cho java.util.Stream chấp nhận các biểu thức lambda cho biết một bộ sưu tập để thực hiện một chức năng.

Điều trị rõ ràng, ngắn gọn và đầy đủ về toàn bộ chủ đề là cuốn sách mới của Maurice Naftalin, Mastering Lambdas - Java Programming in a Multi-Core World.

1

Mã luôn là dữ liệu! Các hướng dẫn bytecode cho một chương trình được lưu trữ trong bộ nhớ. Lập trình viên không có quyền truy cập đọc và ghi trực tiếp vào bộ nhớ này, nhưng nó ở đó.

Khi chúng ta nói về "xử lý" mã dưới dạng dữ liệu, chúng tôi tham khảo lưu trữ các tham chiếu đến bộ nhớ đó theo cách nó có thể được sử dụng và sắp xếp theo cách chúng ta thường nghĩ về "dữ liệu".

Ví dụ, người ta có thể tưởng tượng rằng bên button nó trông giống như sau:

class Button { 
    private ActionListener[] listeners = new ActionListener[100]; 
    private int count = 0; 

    public void addActionListener(ActionListener listener) { 
     listeners[count] = listener; 
     ++count; 
    } 

    // called somehow when the button is clicked 
    void notifyListeners() { 
     ActionEvent theEvent = new ActionEvent(...); 
     for(int i = 0; i < count; ++i) { 
      listeners[i].actionPerformed(theEvent); 
     } 
    } 
} 

Về cơ bản Button là giữ một danh sách các chức năng trong một mảng: đây là đối xử với mã như dữ liệu. Trong hầu hết các trường hợp, ActionListener không phục vụ mục đích nào khác ngoại trừ việc chỉ định một ghi đè cụ thể của actionPerformed.

Vì tất cả các phương pháp thể hiện Java là ảo, chúng tôi luôn có thể coi mã là dữ liệu. Điều này được thể hiện bằng khung lắng nghe sự kiện phức tạp của AWT/Swing. Các biểu thức Lambda chỉ thêm nhấn mạnh khái niệm và cú pháp ngắn. (Ngoài ra một hiệu suất đạt được trong hầu hết các tình huống do thực hiện của họ.)

Lambdas cho phép chúng tôi thể hiện rõ hơn ý định của mình khi chúng tôi đang sử dụng một đối tượng chỉ để thực hiện một phương pháp cụ thể.

Về mặt kỹ thuật, điều này được thực hiện thông qua vô hướng. An ActionListener không giữ mã: thay vào đó, máy ảo biết bằng cách nào đó (rằng chúng tôi không phải là riêng) mà nó trỏ đến một cấu trúc cụ thể trong bộ nhớ mà giữ một con trỏ đến mã. Vì vậy, một số loại tham chiếu đến mã là những gì thực sự được truyền đi xung quanh, do đó "xử lý mã làm dữ liệu".

Các vấn đề liên quan