交换Elisp中的两个变量


20

假设我有

(setq a 1 b 2)

我怎样才能优雅地交换的价值a,并b没有使用临时变量?


虽然我记得很多年前编程示例中的交换操作,但我认为我从来不需要这样的“交换”操作。那么,您在哪里发现您需要这种东西?
Stefan

@Stefan这次,我正在编写一个带有两个参数的函数,并且我想确保第一个参数是两个中较小的一个。
PythonNut

1
@PythonNut,那么您可以将第一个参数绑定到(min a b)第二个参数(max a b)。这是一种解决方案。有人会认为,当一个条件满足时,就需要进行两次比较,这是正确的。您仍然可以通过一种比较比较实用的方式来处理它,例如使用destructuring bind (cl-destructuring-bind (a . b) (if (< a b) (cons a b) (cons b a)) ...)。这是另一种方式。
Mark Karpov 2015年

1
@马克是真的,但至少对我而言,这就像用手榴弹扑打苍蝇。cl-destructuring-bind是完成这项工作的不可思议的强大工具。
PythonNut

Answers:


18

如果记忆对我有好处,而您愿意使用cl-lib

(cl-rotatef a b)

请注意,这是解决问题的Common Lisp方法。


20

这是我使用的优雅成语;-)。

(setq a  (prog1 b (setq b  a)))

1
嘿,很整洁。如果性能令人担忧,我会牢记这一点。
PythonNut

1
巧妙而简单。
命名

1
哦,无论如何,这不是我的本意。但这可能是我主要的用途prog1
画了

1
那几乎就是cl-rotatef宏扩展的范围。
abo-abo

6

如果是整数:

(setq a (logxor a b))
(setq b (logxor a b))
(setq a (logxor a b))

:)


2
为了完整起见,您还应该包括以下经典名称:a = a + b,b = a-b,a = a-b。翻译成Emacs Lisp,当然是:-D
Mark Karpov

1
是的,为了完整起见,我将指出,在X或T的C语言中,XOR技巧适用于任何事物。寄存器,内存,整数,浮点数,结构,字符串(等长)...在Lisp中,我认为只有整数。对于较大的内存块,不需要临时缓冲区是很好的。
jtgd

@jtgd:对于较大的内存块,您可以使用小缓冲区逐段进行交换。
克莱门特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.