在lisp中,我可以将参数传递给函数并在函数内进行更改.(AKA破坏性功能).但是,在Clojure中,我已经读过某个地方,在同一个函数中改变给定的参数是不允许的.例如:
(defn add-two-lists [list1 list2]
(for [n (range (count list1))]
(+ (nth list1 n) (nth list2 n))))
Run Code Online (Sandbox Code Playgroud)
这是一个普通函数,它的输出是两个相同列表的相加.但是,我想要这样的东西:
(defn add-two-lists [list1 list2 added_list]
(set! added_list
(for [n (range (count list1))]
(+ (nth list1 n) (nth list2 n)))))
Run Code Online (Sandbox Code Playgroud)
也许我的使用set!是错误的或误用的,我仍然会得到错误.有没有一种优雅的方法来破坏性地修改Clojure中的参数?
mik*_*era 12
在Clojure中不鼓励进行破坏性修改 - 我鼓励您找到编写代码的方法,而无需借助破坏性更新.
本着给出Clojurey解决方案的精神,我会add-two-lists按如下方式编写您的函数:
(defn add-two-lists [list1 list2]
(map + list1 list2))
Run Code Online (Sandbox Code Playgroud)
这有一些优点:
nth它本身就是列表上的O(n)操作.Clojure提供了几种在这种情况下运行良好的可变类型,例如,你可以传递atom给函数并让它在该atom中设置值.
(defn add-two-lists [list1 list2 added_list]
(reset! added_list
(for [n (range (count list1))]
(+ (nth list1 n) (nth list2 n)))))
Run Code Online (Sandbox Code Playgroud)
然后在你调用它之后你用@/ deref
edit 从原子中获取值:如果效率是目标,那么使用瞬态集合可能会有所帮助