EDIT: Tôi đã thay đổi mã ví dụ sau câu trả lời đầu tiên vì tôi đã nghĩ ra một phiên bản đơn giản hơn để giải quyết vấn đề tương tự.
Tôi hiện đang tìm hiểu về thuộc tính phạm vi của Common Lisp. Sau khi nghĩ rằng mình đã hiểu biết chắc chắn, tôi quyết định viết một số ví dụ mà tôi có thể dự đoán được kết quả, nhưng có vẻ như tôi đã nhầm. Tôi có ba câu hỏi, mỗi câu hỏi liên quan đến ví dụ sau:
Ví dụ 1:
(defmethod fun1 (x)
(in x)
(vui vẻ2))
(defmethod fun2 ()
(in x))
(vui vẻ1 5)
Đầu ra:
5
*** - EVAL: biến X không có giá trị
Câu hỏi: Điều này có ý nghĩa. x nằm trong phạm vi tĩnh, không có cách nào để fun2 tìm thấy giá trị của x mà không chuyển nó một cách rõ ràng.
Ví dụ 2:
(defvar x 100)
(defmethod fun1 (x)
(in x)
(vui vẻ2))
(defmethod fun2 ()
(in x))
(vui vẻ1 5)
Đầu ra:
5
5
Câu hỏi: Tôi không hiểu tại sao x đột nhiên hiển thị với fun2 và giá trị của nó là giá trị do fun1 trao cho nó thay vì 100...
Ví dụ 3:
(bộ x 100)
(defmethod fun1 (x)
(in x)
(vui vẻ2))
(defmethod fun2 ()
(in x))
(vui vẻ1 5)
Đầu ra:
5
100
Câu hỏi: Tôi có nên bỏ qua những kết quả này không, vì việc gọi setf trên một biến không được khai báo rõ ràng là không được xác định? Đây chính xác là những gì tôi mong đợi trong ví dụ thứ hai...
Mọi hiểu biết sâu sắc sẽ được đánh giá rất cao ...
sử dụng setf
Hiệu ứng của việc đặt một biến không xác định là không xác định trong ANSI Common Lisp.
biến đổi
sẽ xác định mộtbiến đặc biệt. Tuyên bố này có tính toàn cầu và cũng đúng đối với cho phép
Sự ràng buộc có tác động. Đây là quy ước viết các biến này dưới dạng *foo*
lý do. Nếu bạn đã từng sử dụng biến đổi
được xác định x
, được khai báo làđặc biệt Và没有Phương thức khai báo nótheo từ vựng sau này.
cho phép
Các biến từ vựng cục bộ được cung cấp theo mặc định. Nếu biến đã được khai báo là biến đặc biệt (ví dụ vì biến đổi
), thì nó sẽ chỉ tạo một liên kết động cục bộ mới (liên kết).
gia hạn
Không có gì để xem.
x
đã được tuyên bố đặc biệt. biến x
Tất cả việc sử dụng hiện nay đều sử dụng liên kết động (liên kết). Khi gọi hàm này, x
绑定(bind)到 5
. một cách năng động. Các hàm khác hiện có thể truy cập liên kết động này và nhận giá trị.
Đây là trong Common Lispkhông xác địnhHành vi. Bạn đang đặt một biến không được khai báo. Điều gì xảy ra sau đó phụ thuộc vào việc thực hiện. Việc triển khai của bạn (hầu hết đều làm điều gì đó tương tự) sẽ là x
củagiá trị ký hiệu设置为100
. hiện hữu vui1
ở giữa,x
Nó bị ràng buộc về mặt từ vựng. hiện hữu vui2
trung bình, đánh giá x
Sẽ tìm kiếm x
giá trị tượng trưng (hoặc có thể là giá trị ràng buộc động).
Như một ví dụ về việc thực hiện (thực hiện?) các hoạt động khác: Theo mặc định, việc triển khai CMUCL cũng sẽ x
Tuyên bố là đặc biệt. Đặt một biến không xác định cũng tuyên bố nó là đặc biệt.
Để ý
Trong mã Common Lisp phù hợp với tiêu chuẩn di động, các biến toàn cục được biến đổi
Và thông số sai lệch
được xác định. Cả hai đều khai báo các biến này là đặc biệt. Tất cả việc sử dụng các biến này hiện nay đều liên quan đến ràng buộc động.
nhớ:
((lambda (x)
(tội lỗi x))
10)
Về cơ bản là giống nhau
(hãy ((x 10))
(tội lỗi x))
这意味着 cho phép
Liên kết biến trong các liên kết hoạt động giống như liên kết biến trong các lệnh gọi hàm. nếu như x
Được khai báo là đặc biệt ở đâu đó trước đó, khi đó cả hai sẽ liên quan đến liên kết động (liên kết).
Điều này được quy định trong tiêu chuẩn Common Lisp. Xem ví dụ Tuyên bố ĐẶC BIỆT lời giải thích.
Tôi là một lập trình viên xuất sắc, rất giỏi!