Có thể các động dựng sẵn được ngầm bọc trong một hình thức ràng buộc bởi thời gian chạy? Bởi vì việc này, ví dụ:
user=> (def ^:dynamic *x*)
user=> (binding [*x* false] (set! *x* true))
true
user=>
Một điều cần lưu ý là các tài liệu một cách rõ ràng nói rằng một lỗi của mình để thử và sửa đổi gốc rễ ràng buộc qua set!
, xem:
http://clojure.org/reference/vars
Đó là cũng có thể các nội trang được xử lý đặc biệt, ví dụ: nếu bạn xem siêu dữ liệu của x:
user=> (meta #'*x*)
{:dynamic true, :line 1, :column 1, :file "/private/var/folders/8j/ckhdsww161xdwy3cfddjd01d25k_1q/T/form-init5379741350621280680.clj", :name *x*, :ns #object[clojure.lang.Namespace 0x6b8f00 "user"]}
Nó đánh dấu là năng động, trong khi *warn-on-reflection*
không được đánh dấu như năng động nhưng vẫn hoạt động trong một hình thức ràng buộc:
user=> (meta #'*warn-on-reflection*)
{:added "1.0", :ns #object[clojure.lang.Namespace 0x377fc927 "clojure.core"], :name *warn-on-reflection*, :doc "When set to true, the compiler will emit warnings when reflection is\n needed to resolve Java method calls or field accesses.\n\n Defaults to false."}
user=> (binding [*warn-on-reflection* true] (set! *warn-on-reflection* false))
false
user=>
Có lẽ đây là để tương thích ngược bởi vì trong phiên bản trước của clojure vars với earmuffs (ngôi sao trong mỗi bên) là năng động theo quy ước. Nhưng dù sao, điều này chỉ cho thấy rằng nội trang được xử lý hơi khác nhau.
Bây giờ, tôi đã quyết định để thực hiện việc này một chút nữa, và grep
mã nguồn của clojure, tìm kiếm warn-on-reflection
, dẫn tôi đến liên tục WARN_ON_REFLECTION
, dẫn tôi tới dòng mã như thế này trong RT.java
:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L467
Var.pushThreadBindings(
RT.mapUniqueKeys(CURRENT_NS, CURRENT_NS.deref(),
WARN_ON_REFLECTION, WARN_ON_REFLECTION.deref()
,RT.UNCHECKED_MATH, RT.UNCHECKED_MATH.deref()));
dẫn tôi tin rằng giả định ban đầu của tôi là đúng, rằng nhất định vars toàn cầu đặc biệt được mặc nhiên được bao bọc trong một thread địa phương ràng buộc.
EDIT:
Như đã đề cập trong một chú thích, bạn có thể sử dụng clojure.core/push-thread-bindings
, nhưng hãy chắc chắn để làm theo lời khuyên của các tài liệu và quấn trong try/catch/finally với pop-thread-bindings
trong khối finally. Và tại thời điểm đó, bạn sẽ chỉ được triển khai lại binding
(ví dụ: chạy (source binding)
khi phát lại), đó có thể là lý do tại sao tài liệu cảnh báo rõ ràng rằng push-thread-bindings
là chức năng cấp thấp và cần ưu tiên binding
.
Bây giờ tôi thấy, cảm ơn! Ngoài ra [đó là lý do] (https://github.com/clojure/clojure/blob/d920ada9fab7e9b8342d28d8295a600a814c1d8a/src/jvm/clojure/lang/RT.java#L228) Tôi không thể tìm thấy định nghĩa '* cảnh báo-on- phản ánh * 'trong' clojure.core'. – OlegTheCat
Bạn có thể muốn thêm rằng bạn có thể làm cho biến động của riêng bạn hoạt động tương tự với https://clojuredocs.org/clojure.core/push-thread-bindings. – coredump