簡體   English   中英

為什么 clojure repl 在取消映射后顯示 var 與符號相關聯?

[英]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 將yz打印為#'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 中的工作原理。

  • var 是一個可變的存儲位置,可選地由命名空間符號命名。
  • 命名空間是一個 map 從符號到變量。
  • 如果命名空間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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM