Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function Lisp-在函数的多个语句中修改局部变量_Function_Variables_If Statement_Lisp_Local - Fatal编程技术网

Function Lisp-在函数的多个语句中修改局部变量

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

我是lisp新手,试图理解lisp是如何工作的,但我不知道如何在一个大函数中使用局部变量。 这里我有一个小例子,我把一个数字发送给一个函数,如果它可以被3,5和7整除,我必须返回一个列表(by3by5by7),如果只被7整除,返回(by7),依此类推。。。。 这是我的密码:

(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
不会变异任何内容。非常感谢!非常感谢你!