编程我的第一个Clojure程序我偶然发现了以下任务,我无法解决:
(ns core
(:require [calc]))
(def data 1)
(calc/updatedata)
data
;; should return 2
(ns calc)
(refer 'core :only '[data])
(defn updatedata []
(def data (+ 1 data)))
现在我有两个问题:
core
需要calc
,首先会调用calc
,但之后还没有符号data
。我不知道怎么解决这个问题:(data
重新定义def
,收到错误java.lang.IllegalStateException: data already refers to #'core/data in namespace: calc
。也许我应该在这里使用ref / atom / agent(还没有和那些人一起工作但是我现在正在研究它......)?如何在core/data
中引用和变异calc
,就像在那里定义一样?
答案 0 :(得分:2)
作为RedDeckWins提议的扩展,如果您希望在core
中发生变异并避免将data
传递给calc
中的每个函数,您可以在calc
中创建动态变量{1}}。在update-data
中的第一个语句,您将传入的值绑定到动态var。 calc
中所有相关函数总是引用动态变量。
(ns noob-1.calc)
(def ^:dynamic *app-data* {:val false})
(defn action-1 []
(println "action-1 data - " *app-data*))
(defn action-2 []
(println "action-2 data - " *app-data*))
(defn actions [data]
(binding [*app-data* data]
(println "actions data - " *app-data*)
(action-1)
(action-2)
(assoc *app-data* :val "2")))
(ns noob-1.core
:require [noob-1.calc :as calc])
(def app-data (atom {:val "1"}))
(defn calc-stuff []
(swap! app-data calc/actions))
尽管如此,我仍然建议将app-data
传递给calc
中的每个功能。这样,每个函数都可以逐步修改app-data
,actions
可以返回最终状态。为了支持突变并避免将状态传递给每个函数,您需要用原子替换动态var。 calc
中的原子将在本地使用,其值从actions
返回。我会避免这种情况。
答案 1 :(得分:1)
在我看来,你完全错误地做了这个,并且可能对你应该如何在Clojure中编程有一个根本的误解,但是我们走了。
(ns clojure-scratch.core
(:require [clojure-scratch.calc :as calc]))
(def data (atom 1))
(swap! data calc/update-data)
在另一个档案中
(ns clojure-scratch.calc)
(defn update-data [n]
(inc n))