Sau khi đọc rất nhiều về Lisp đánh giá khi nào
Sau khi xem tài liệu về toán tử, tôi vẫn không hiểu nó làm gì, tôi biết rằng bằng cách sử dụng toán tử này, tôi có thể kiểm soát thời điểm một biểu thức đánh giá, nhưng tôi không thể tìm ra bất kỳ ví dụ nào có thể áp dụng điều này?
Trân trọng, utxee.
Biên soạn các tập tin Lisp
Lấy việc biên dịch các tệp Lisp làm ví dụ. Trình biên dịch Lisp xử lý các biểu mẫu cấp cao nhất. Đây có thể là bất kỳ dạng Lisp, DEFUN, DEFMACROS, DEFCLASS, lệnh gọi hàm nào...
Toàn bộ câu chuyện về cách thức hoạt động của trình biên dịch tệp quá phức tạp để có thể giải thích ở đây, nhưng có một số điều sau:
Trình biên dịch tập tin là (DEFUN foo () )
Mã tạo biểu mẫu. Nhưng nó không thực hiện hình thức defun. Bằng cách này, bạn sẽ biết rằng có một hàm khi biên dịchFOO
, nhưng khi biên dịch lại không có mã cho ˋFOOˋ. Trình biên dịch tạo mã cho tệp đã biên dịch nhưng không lưu nó vào bộ nhớ. Bạn không thể gọi hàm như vậy vào thời gian biên dịch.
Đối với macro, nó hoạt động hơi khác một chút:(DEFMACRO BAZ...)
. Trình biên dịch tệp không chỉ biên dịch macro và ghi lại sự hiện diện của nó mà còn cung cấp macro tại thời điểm biên dịch. nó được tải vào trình biên dịchmôi trường中。
Hãy tưởng tượng thứ tự của các biểu mẫu trong tệp:
(defmacro baz...)
(defun foo () (baz ...))
Điều này hoạt động vì trình biên dịch tệp biết về macro BAZ
, khi nó biên dịch FOO
của mã, nó có thể mở rộng dạng macro.
Bây giờ chúng ta hãy xem ví dụ sau:
(thanh defun (dạng) ...)
(defmacro baz (dạng) (dạng thanh))
(defun foo () (baz ...))
Không có cách nào ở trên hoạt động. bây giờ là vĩ mô BAZ
bằng cách gọi hàm THANH
để sử dụng nó. Khi trình biên dịch cố gắng biên dịch một hàm FOO
Nó không thể được mở rộng khi BAZ
Macro, vì nó không thể được gọi THANH
,因为THANH
Mã không được tải vào môi trường thời gian biên dịch.
Có hai giải pháp:
- Biên dịch bằng các tệp riêng biệtVà加载
THANH
.
- sử dụngĐÁNH GIÁ- KHI NÀO
ĐÁNH GIÁ- KHI NÀO
Ví dụ:
(eval-when (:compile-toplevel :execute :load-toplevel)
(thanh defun (dạng) ...)
)
(defmacro baz (dạng) (dạng thanh))
(defun foo () (baz ...))
Hiện nay ĐÁNH GIÁ- KHI NÀO
Hướng dẫn trình biên dịch tệp thực sự chạy biểu mẫu DEFUN trong quá trình biên dịch. Tác dụng của việc này là: trình biên dịch tập tin bây giờthời gian biên dịch BiếtTHANH
sự định nghĩa. Vì vậy, khi trình biên dịch tập tin cần sử dụng BAZ
được gọi trong quá trình mở rộng vĩ mô của THANH
, nó có sẵn.
chỉ có thể được sử dụng:compile-toplevel
, khi chức năng này không cần thiết sau khi tệp được biên dịch. Nếu chúng ta sử dụng nó sau này thì chúng ta cần đảm bảo rằng nó đã được tải.
所以 ĐÁNH GIÁ- KHI NÀO
Cho phép chỉ định xem có nên chạy một đoạn mã cụ thể hay không
- Trong quá trình biên soạn tập tin
- Trong quá trình tải tập tin
- Trong quá trình thực hiện
ĐÁNH GIÁ- KHI NÀO
Không thường xuyên được sử dụng trong mã người dùng. Nếu bạn sử dụng nó, thì bạn nên tự hỏi liệu bạn có thực sự cần nó hay không.
Tôi là một lập trình viên xuất sắc, rất giỏi!