Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用var quote语法调用Clojure函数_Clojure_Eval_Var - Fatal编程技术网

使用var quote语法调用Clojure函数

使用var quote语法调用Clojure函数,clojure,eval,var,Clojure,Eval,Var,偶尔在查看其他人的Clojure代码时,我会看到通过defn定义的函数,然后使用var quote语法调用,例如: user> (defn a [] 1) #'user/a user> (a) ; This is how you normally call a function 1 user> (#'a) ; This uses the var-quote syntax and produces the same result 1 就我个人而言,我无法理解这两种调用函数的

偶尔在查看其他人的Clojure代码时,我会看到通过
defn
定义的函数,然后使用var quote语法调用,例如:

user> (defn a [] 1)
#'user/a
user> (a)   ; This is how you normally call a function
1
user> (#'a) ; This uses the var-quote syntax and produces the same result
1
就我个人而言,我无法理解这两种调用函数的方式之间的区别。我在文档中找不到任何东西可以说明当调用的操作符是var时会发生什么,这可能表明为什么会首选第二种形式。它们对
绑定
赋值和语法引用的响应似乎相同

那么,有人能提供一个代码示例来说明上面的
(a)
(#'a)
之间的区别吗

编辑:我知道var quote可以用来获取被
let
词法绑定隐藏的var,但我看到的代码似乎不是这样。

(#a)
总是指var
a
,而
(a)
可以被本地绑定隐藏:

user> (defn a [] 1)
#'user/a
user> (let [a (fn [] "booh")] [(a) (#'a)])
["booh" 1]
但是,var quote/函数调用的大多数实际用途不是直接调用var quote表达式,而是缓存其值,以便高阶构造在传入时引用var a的当前值,而不是其值:

(defn a [] 1)
(defn my-call [f] (fn [] (+ 1 (f))))
(def one (my-call a))
(def two (my-call #'a))
(defn a [] 2)

user> (one)
2
user> (two)
3

这对于交互式开发非常有用,在交互式开发中,您正在更改一些函数,这些函数被包装在其他包中的一组其他函数中

第二种形式允许您绕过clojure设置的隐私限制

因此,例如,如果您开发了一个带有私有函数的库,但希望从一个单独的名称空间测试它们,那么您不能直接引用它们。但是您可以使用var quote语法访问它们。这是非常有用的

隐私是clojure本质上是一种自动文档,与Java中的隐私不同。你可以绕过它

user> (defn- a [] 1)
#'user/a
user> (ns user2)
nil
user2> (user/a)
CompilerException java.lang.IllegalStateException: var: #'user/a is not public,    compiling:(NO_SOURCE_PATH:1) 
user2> (#'user/a)
1
user2> 

很好的一点——既然你提到了这一点,我记得过去我自己也做过。但是我看到的代码是调用非私有fn,所以我认为避免缓存当前绑定的值是更可能的解释,因为代码在私有回购中。我发布了一个一般性问题,得到了两个好答案,只能接受一个,所以我接受了一个我觉得更好的问题,回答了一般情况。