是否有任何快速方法可以将闭包恢复或重置为初始状态?例如。在下面的函数中,如何将与myClosureFn关联的stat1和stat2的值重置为1?
这个问题的上下文:我在不同函数中使用下面的结构,并且一个函数可能“搞乱”与闭包相关联的值。所以我需要将其重置/恢复到初始状态,以便再次将其传递给另一个函数。
(def myClosureFn
(let [stat1 (atom 1)
stat2 (atom 1)
;..stat3 stat4 ...
]
(fn [m]
(swap! stat1 inc)
(reset! stat2 (* 2 m))
[@stat1 @stat2])))
(myClosureFn 1) ;--> [2 2]
(myClosureFn 2) ;--> [3 4]
(myClosureFn 2) ;--> [4 4]
(myClosureFn 3) ;--> [5 6]
;...
; how to get [ 1 1 ] back to myClosureFn ?
答案 0 :(得分:3)
不要明确地重新设置与函数关联的状态,而应考虑使用更高阶函数:
(defn myClosureFn []
(let [stat1 (atom 1)
stat2 (atom 1)
;..stat3 stat4 ...
]
(fn [m]
(swap! stat1 inc)
(reset! stat2 (* 2 m))
[@stat1 @stat2])))
因此,要获得新状态,只需调用myClosureFn
,它返回一个带有干净计数器的函数。例如:
> (def f1 (myClosureFn))
> (def f2 (myClosureFn))
> (f1 1) ;--> [2 2]
> (f1 2) ;--> [3 4]
> (f2 1) ;--> [2 2]
> (f1 3) ;--> [4 6]
每个函数都有自己的状态,而不是具有全局状态。您甚至可以同时创建和使用两个这样的函数,它们不会相互干扰。
答案 1 :(得分:2)
当没有传递参数时,您可以使myClosureFn
像重置函数一样工作
(def myClosureFn
(let [stat1 (atom 1)
stat2 (atom 1)
;..stat3 stat4 ...
]
(fn [& [m]]
(if m
(do
(swap! stat1 inc)
(reset! stat2 (* 2 m))
[@stat1 @stat2])
(do
(reset! stat1 1)
(reset! stat2 1))))))
(myClosureFn 1) ;--> [2 2]
(myClosureFn 2) ;--> [3 4]
(myClosureFn) ;reset to 1 1
如果您使用REPL,则只需在REPL中重新评估myClosureFn
表单。