[英]Why does the clojure repl show that a var is associated with a symbol, after it's been unmapped?
假設我在 Clojure 命名空間中創建了一個變量x
,將關聯的 var 存儲在另一個變量 ( y
) 中,然后取消映射x
:
(ns user)
(def x 0)
(def y (var x))
(ns-unmap 'user 'x)
如果我在 REPL 中評估y
,它會打印#'user/x
,即使符號user/x
不再與該變量相關聯。
user=> y
#'user/x
user=> (deref y)
0
user=> (deref #'user/x)
Syntax error compiling var at (REPL:0:0).
Unable to resolve var: user/x in this context
如果我創建一個與符號x
關聯的新變量,事情就會變得非常混亂:
(def x 1)
(def z (var x))
現在,repl 將y
和z
打印為#'user/x
,即使這些變量指向不同的 var 對象:
user=> y
#'user/x
user=> (deref y)
0
user=> z
#'user/x
user=> (deref z)
1
user=> (= z y)
false
為什么 REPL 在此處計算y
時打印#'user/x
?
要正確考慮這一點,您需要了解變量和名稱空間在 Clojure 中的工作原理。
n
具有名為s
的定義,則它將符號n/s
映射到由n/s
命名的 var。 因此,您定義了x
,生成一個標記為user/x
並包含 0 的 var(稱之為v
),並存儲在命名空間user
中。 然后您從user
名稱空間中刪除了該映射。 但是 var v
仍然存在,並且仍然知道它叫做user/x
。 所以你仍然可以通過遍歷y
來查看它,它當然保存了實際的 var object,並且不再關心使用什么命名空間來查找 var。 例如,您可以打印它的名稱並取消引用它以查看鎖定在其中的值 0。
您稍后在user
命名空間中定義一個名為x
的新變量,生成一個知道它被user/x
引用的新變量。 但它是一個不同的 var,因此它們可以保存不同的值,並且user
命名空間現在指向一個與您存儲在y
中的不同的 var。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.