Function Lisp-在函数的多个语句中修改局部变量
我是lisp新手,试图理解lisp是如何工作的,但我不知道如何在一个大函数中使用局部变量。 这里我有一个小例子,我把一个数字发送给一个函数,如果它可以被3,5和7整除,我必须返回一个列表(by3by5by7),如果只被7整除,返回(by7),依此类推。。。。 这是我的密码:Function Lisp-在函数的多个语句中修改局部变量,function,variables,if-statement,lisp,local,Function,Variables,If Statement,Lisp,Local,我是lisp新手,试图理解lisp是如何工作的,但我不知道如何在一个大函数中使用局部变量。 这里我有一个小例子,我把一个数字发送给一个函数,如果它可以被3,5和7整除,我必须返回一个列表(by3by5by7),如果只被7整除,返回(by7),依此类推。。。。 这是我的密码: (defun checknum(n) let* (resultt '() ) ( if(not(and(plusp n ) (integerp n))) (cons nil resultt) (prog
(defun checknum(n)
let* (resultt '() ) (
if(not(and(plusp n ) (integerp n))) (cons nil resultt) (progn
(if (zerop (mod n 7)) (cons 'by7 resultt) (cons nil resultt))
(if (zerop (mod n 5)) (cons 'by5 resultt) (cons nil resultt))
(if (zerop (mod n 3)) (cons 'by3 resultt) (cons nil resultt) )) ))
但是如果我发送21作为ex,我只得到nil,而不是(by3by7),我想局部变量不受if语句的影响,我不知道如何做…(cons x y)
创建一个新的cons单元格并处理结果。要更改变量的值,需要使用setq
、setf
、push
等,例如:
(defun checknum (n)
(let ((resultt nil))
(when (and (plusp n) (integerp n))
(when (zerop (mod n 7)) (push 'by7 resultt))
(when (zerop (mod n 5)) (push 'by5 resultt))
(when (zerop (mod n 3)) (push 'by3 resultt)))
resultt))
或者,更优雅地使用内部函数来消除重复:
(defun checknum (n)
(when (and (plusp n) (integerp n))
(labels ((sub (d nsym res)
(if (zerop (mod n d))
(cons nsym res)
res)))
(sub 7 'by7
(sub 5 'by5
(sub 3 'by3 nil)))))
测试:
CL-USER> (checknum 12)
(BY3)
CL-USER> (checknum 15)
(BY3 BY5)
CL-USER> (checknum 105)
(BY3 BY5 BY7)
CL-USER> (checknum 21)
(BY3 BY7)
(cons x y)
创建一个新的cons单元格并处理结果。要更改变量的值,需要使用setq
、setf
、push
等,例如:
(defun checknum (n)
(let ((resultt nil))
(when (and (plusp n) (integerp n))
(when (zerop (mod n 7)) (push 'by7 resultt))
(when (zerop (mod n 5)) (push 'by5 resultt))
(when (zerop (mod n 3)) (push 'by3 resultt)))
resultt))
或者,更优雅地使用内部函数来消除重复:
(defun checknum (n)
(when (and (plusp n) (integerp n))
(labels ((sub (d nsym res)
(if (zerop (mod n d))
(cons nsym res)
res)))
(sub 7 'by7
(sub 5 'by5
(sub 3 'by3 nil)))))
测试:
CL-USER> (checknum 12)
(BY3)
CL-USER> (checknum 15)
(BY3 BY5)
CL-USER> (checknum 105)
(BY3 BY5 BY7)
CL-USER> (checknum 21)
(BY3 BY7)
大多数lisp表单/函数不修改其参数。这样做的人将被明确记录为这样做。例如,请参见“邻接”和“新建”,或“删除”和“删除” 至于“试图理解lisp是如何工作的”,以各种不同的方式编写同一个函数对我帮助很大,因此您可能需要考虑如何在不修改变量的情况下编写函数,以及为什么和何时希望/不希望使用破坏性修改 下面这样的代码会进行两次传递,如果需要检查大量的数字,但不会破坏性地修改任何内容,那么速度会太慢
(defun checknum (n)
(remove nil
(mapcar #'(lambda (m sym)
(when (zerop (mod n m)) sym))
'(7 5 3)
'(by7 by5 by3))))
上述方法可以编写为不需要两次传递等。大多数lisp表单/函数不修改其参数。这样做的人将被明确记录为这样做。例如,请参见“邻接”和“新建”,或“删除”和“删除” 至于“试图理解lisp是如何工作的”,以各种不同的方式编写同一个函数对我帮助很大,因此您可能需要考虑如何在不修改变量的情况下编写函数,以及为什么和何时希望/不希望使用破坏性修改 下面这样的代码会进行两次传递,如果需要检查大量的数字,但不会破坏性地修改任何内容,那么速度会太慢
(defun checknum (n)
(remove nil
(mapcar #'(lambda (m sym)
(when (zerop (mod n m)) sym))
'(7 5 3)
'(by7 by5 by3))))
上述方法可以编写为不需要两次通过,等等。请编辑问题并改进代码格式。
progn
块的结果是块中最后一个表达式的值,和cons
不会变异任何内容。请编辑问题并改进代码的格式。progn
块的结果是块中最后一个表达式的值,cons
不会变异任何内容。非常感谢!非常感谢你!