i++;Clojure中的等价物

i++;Clojure中的等价物,clojure,Clojure,我是新来Clojure的 在Clojure中有增加变量的快捷方式吗 在许多语言中,这将起作用: i++; i += 1; 在Clojure中,我可以做到: (def i 1) (def i (+ i 1)) 这是Clojure中增加绑定的正确方法吗 有快捷方式吗?您可以编写(inc i)来增加整数或长整数 (def i 1) (def i+1 (inc i)) 如果您需要将(inc i)分配给i本身,请说明您为什么要这样做。在大多数情况下,clojure会有一个更优雅(或惯用)的解

我是新来Clojure的

在Clojure中有增加变量的快捷方式吗

在许多语言中,这将起作用:

i++;
i += 1;
在Clojure中,我可以做到:

(def i 1)    
(def i (+ i 1))
这是Clojure中增加绑定的正确方法吗

有快捷方式吗?

您可以编写
(inc i)
来增加整数或长整数

(def i 1)
(def i+1 (inc i))

如果您需要将
(inc i)
分配给
i
本身,请说明您为什么要这样做。在大多数情况下,clojure会有一个更优雅(或惯用)的解决方案。

您不能在clojure或任何其他lisp中为
i
分配新值<代码>i将在当前上下文中只有一个值
(inc i)
返回一个新值,该值可能绑定到新的局部变量,也可能不绑定到新的局部变量

这就是为什么在lisp语言中,尾部递归优化如此重要的原因;因为模拟循环的唯一方法是递归,在每次函数调用时,索引都有一个新值。尾部递归优化通过将递归转换为一个简单的旧循环,避免了一个非常长的循环耗尽堆栈

clojure通过使用
recur
函数再次调用同一个函数来保证尾部递归优化会发生。如果无法进行尾部递归优化,
recur
将给出编译时错误


编辑这是易变习语的精髓。不可变性和函数式编程之间有着紧密的联系。原因是函数编程意味着“无副作用的代码”,或者更准确地说,函数在计算中的唯一影响是通过其返回值。实现这一点的一种方法是在上述意义上默认设置参数和变量为inmutable。尽管现在从其他海报上你已经意识到有很多方法可以解决这个问题,而不是依赖clojure中的不可变性,你可以使用一个原子来交换它的价值


(let [i (atom 0)]
  (println @i)
  (swap! i inc)
  (println @i))
我会给你

0
1

请注意,我写道:“这将起作用”而不是“它将起作用”,并且=+在Java中起作用根本不做任何事情。我的意思是它没有任何效果。注意:当你不得不这样做的时候,你可能做错了。我强烈建议您阅读有关函数式编程的内容和/或在irc频道、邮件列表或stackoverflow上寻求帮助。谢谢。你能解释一下第二行的i+1是什么吗?它只是一个变量名在clojure中没有特别的意义。我认为他不理解不应该在clojure中进行破坏性更新。嗨,我想做一个计数器,指定某人单击按钮的次数。。。如何制作这个计数器?尾部递归不是循环/迭代的唯一解决方案;懒惰是另一个原因<代码>重复为低级别;Clojure中的大多数循环需求都可以通过lazy seqs+
doseq
for
map
reduce
和friends来处理。您可以在common lisp中直接更改变量的值,例如使用我知道的setq/setf/etc函数,但允许他以正确的方式学习函数样式-然后,一旦他掌握了它,就让他打破它。我认为大多数lisp方言都允许可变变量,用错误的陈述来鼓励良好的行为是没有意义的。对于阅读本文的任何人来说。。。正如@ArthurUlfeldt提到的那样。状态在公共lisp中是可变的。常见的Lisp标准不需要实现尾部调用优化(尽管主要的实现是这样的)。+1我经常发现这个技巧很有用,尽管值得补充一点,即这样做不是很好/惯用的函数风格!