如何传递函数引用而不是函数本身?

杰森·巴萨尼斯(Jason Basanese)

让我们说我们定义了my-function将要打印的功能"message1"接下来,在repl中,我们定义使用该函数的原子。

(def key-func (atom {:func my-function}))

之后,我将功能更新my-function为print "message2"现在,当我运行((:func @key-func))时,它会打印出来"message1"我最终不得不重新加载原子。这会使我相信,{:func my-function}不是将对实际函数的引用与之配对,:func而是传递了当时函数的副本。那么,是否可以传递函数指针而不是副本?

TLDR;

(defn my-func [] (print "message1"))
(def key-func (atom {:func my-func}))
(defn my-func [] (print "message2"))
((:func @key-func)) ;prints message1 instead of message2
艾伦·汤普森(Alan Thompson)

简短答案

看到以下问题:什么时候使用Var而不是函数?

更长的答案

您以非标准方式使用原子。我认为以下内容更接近您想要的内容:

(defn f1 [] "#1")
(defn f2 [] "#2")


(def my-fn (atom f1))
(println :1 (@my-fn))
(reset! my-fn f2)
(println :2 (@my-fn))

产生:

:1 #1
:2 #2

最长版本

此示例显示了复制函数与复制指向函数的var之间的区别:

; This will not work, since his-fn saves a ref to the 
; immutible "All yours baby!" function
(newline)
(println "-----------------------------------------------------------------------------")
(defn your-fn [] (println "All yours baby!"))
(your-fn)  ;=> "All yours baby!"
(def  his-fn your-fn)
(his-fn)   ;=> "All yours baby!"
(defn your-fn [] (println "And it still is!"))
(his-fn)   ;=> "All yours baby!"

; This will work, since both his-fn and her-fn save a reference 
; to the var `your-fn`, which in turn points to first to 
; one function and then to a second function.
(newline)
(println "-----------------------------------------------------------------------------")
(defn your-fn [] (println "All yours baby!"))
(your-fn)
(def  his-fn (var your-fn))
(def  her-fn    #'your-fn)
(his-fn) 
(her-fn) 
; change what var "your-fn" points to
(defn your-fn [] (println "And now you belong to me..."))
(his-fn) 
(her-fn) 

结果:

;-----------------------------------------------------------------------------
;=> All yours baby!
;=> All yours baby!
;=> All yours baby!

-----------------------------------------------------------------------------
;=> All yours baby!
;=> All yours baby!
;=> All yours baby!
;=> And now you belong to me...
;=> And now you belong to me...

警告

在显示了var的行为方式后,请记住,重新定义诸如(def ...)和的顶级表单是不好的(defn ...)通常最好使用原子或局部变量来保存变化的值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章