用函数创建clojure原子
我想1)用下面的函数创建一个符号列表;然后2)使用这些符号/名称创建原子,以便可以从其他函数修改原子。这是生成符号/名称的函数:用函数创建clojure原子,clojure,Clojure,我想1)用下面的函数创建一个符号列表;然后2)使用这些符号/名称创建原子,以便可以从其他函数修改原子。这是生成符号/名称的函数: (defn genVars [ dist ] (let [ nms (map str (range dist)) neigs (map #(apply str "neig" %) nms) ] (doseq [ v neigs ] (intern *ns* (symbol v) [ ] )) )) 如果di
(defn genVars [ dist ]
(let [ nms (map str (range dist)) neigs (map #(apply str "neig" %) nms) ]
(doseq [ v neigs ]
(intern *ns* (symbol v) [ ] ))
))
如果dist=3,则3个符号,neig0。。。neig2是使用空向量创建的每个绑定。如果有可能用这些符号在功能上创建原子,以便可以从其他功能访问它们。非常感谢您的帮助,即使有其他方法可以实现这一点。想要生成名称,您最好使用一个地图:
(def neighbours (atom (make-neighbours)))
其中,make neigbours
的定义可能如下所示:
(defn make-neighbours []
(into {} (for [i (range 10)]
[(str "neig" i) {:age i}])))
另一个命名空间将使用以下内容查找值:
(get-in @data/neighbours ["neig0" :age])
惯用的Clojure倾向于避免创建许多命名的全局变量,而更喜欢将状态并置到一个或几个由Clojure的并发原语(atom/ref/agent)控制的变量中。我鼓励您考虑是否可以用一个原子以这种方式解决您的问题,而不需要定义多个变量
已经说过,如果你真的需要多个原子,考虑将它们全部存储在一个MAP VAR中,而不是创建许多全局VAR。就我个人而言,我从来没有遇到过这样一种情况,即创建多个原子比创建一个大原子更好(因此,我很想听听这一点很重要的情况)
如果您确实需要很多变量,请注意在函数中定义变量实际上是一种糟糕的样式()。也有很好的理由!使用函数和数据的美妙之处在于函数的纯洁性<函数内部的code>def尤其令人讨厌,因为它不仅是一个副作用,而且是一个可能改变执行流的副作用 当然,正如另一个答案所指出的,有一种方法可以实现这一目标 在定义超出def
和defn
的内容时,使用宏有很多优先权。例如,来自compojure的defroutes
,来自Schema的defschema
,来自clojure.test的deftest
。一般来说,任何创建变量的方便形式。可以使用宏解决方案为原子创建DEF:
(defmacro defneighbours [n]
`(do
~@(for [sym (for [i (range n)]
(symbol (str "neig" i)))]
`(def ~sym (atom {}))))
在我看来,这实际上比功能版本更具攻击性,只是因为它创建了全局def。使用常规的def
语法创建全局def更为明显。但我只是把它当作救命稻草提出来,因为这仍然很糟糕
函数和数据工作得最好的原因是它们组成了
有一些具体的考虑因素使得单个原子控制状态非常方便。您可以方便地迭代所有邻居,还可以动态添加新邻居。您还可以做一些事情,比如将邻居与其他邻居连接起来等。如果您创建了许多全局变量,那么基本上有很多函数/数据抽象将您自己锁在外面
这就是为什么宏通常被认为对语法技巧有用,但最好避免使用函数和数据。它对代码的灵活性有着真正的影响。例如,回到compojure;宏语法实际上非常有限,因此我不喜欢使用defroutes
总之:
生成名称的愿望表明,使用单一地图会更好:
(def neighbours (atom (make-neighbours)))
其中,make neigbours
的定义可能如下所示:
(defn make-neighbours []
(into {} (for [i (range 10)]
[(str "neig" i) {:age i}])))
另一个命名空间将使用以下内容查找值:
(get-in @data/neighbours ["neig0" :age])
惯用的Clojure倾向于避免创建许多命名的全局变量,而更喜欢将状态并置到一个或几个由Clojure的并发原语(atom/ref/agent)控制的变量中。我鼓励您考虑是否可以用一个原子以这种方式解决您的问题,而不需要定义多个变量
已经说过,如果你真的需要多个原子,考虑将它们全部存储在一个MAP VAR中,而不是创建许多全局VAR。就我个人而言,我从来没有遇到过这样一种情况,即创建多个原子比创建一个大原子更好(因此,我很想听听这一点很重要的情况)
如果您确实需要很多变量,请注意在函数中定义变量实际上是一种糟糕的样式()。也有很好的理由!使用函数和数据的美妙之处在于函数的纯洁性<函数内部的code>def尤其令人讨厌,因为它不仅是一个副作用,而且是一个可能改变执行流的副作用 当然,正如另一个答案所指出的,有一种方法可以实现这一目标 在定义超出def
和defn
的内容时,使用宏有很多优先权。例如,来自compojure的defroutes
,来自Schema的defschema
,来自clojure.test的deftest
。一般来说,任何创建变量的方便形式。可以使用宏解决方案为原子创建DEF:
(defmacro defneighbours [n]
`(do
~@(for [sym (for [i (range n)]
(symbol (str "neig" i)))]
`(def ~sym (atom {}))))
在我看来,这实际上比功能版本更具攻击性,只是因为它创建了全局def。使用常规的def
语法创建全局def更为明显。但我只是把它当作救命稻草提出来,因为这仍然很糟糕
原因