如何在Lisp中增加变量

时间:2016-07-13 16:31:50

标签: lisp autolisp

以下是代码中的问题:

    (foreach n l_pt
        (write-line
            (strcat "sommet" str_sep
                (itoa (setq (nbs (+1 nbs )))) str_sep
                (rtos (car n) 2 2) str_sep
                (rtos (cadr n) 2 2) str_sep
                (strcat "2") str_sep
                (strcat "borne")
            )
            f_open
        )
    )
    ;;(write-line "" f_open)

我在输出中有这些文件:

  

Sommets ;;

     

类型;民; X; Y;精密级;自然

     

sommet; 1; 1532292.16; 3214140.11; 2;传

     

sommet; 2; 1532287.08; 3214140.60; 2;传

     

sommet; 1; 1532291.45; 3214136.43; 2;传

     

sommet; 2; 1532286.50; 3214135.87; 2;传

     

sommet; 1; 1532287.08; 3214140.60; 2;传

正如您所猜测的,有问题的部分是" Num"这是没有按预期工作的,递增。

我已经理解了这一行:" (itoa(setq(nbs(+1 nbs))))str_se"没有按预期工作,但我不知道为什么。我试图将其切换为(setq(nbs(+ 1 nbs))),但它也不起作用。

你对它的来源有什么想法吗?

Complete code

2 个答案:

答案 0 :(得分:1)

我认为问题在于你只是一个括号。或者您需要在重复之外初始化nbs。这取决于你希望它如何工作。

看起来您的代码(大大简化)是这样的:

;; Stuff before the problem
(repeat (sslength js)
    ;; (setq....)
    (setq nbs 0)
    ;;; Lots of stuff
    (foreach n l_pt
        ;; The printing code including...
        (setq nbs (+ 1 nbs))
    )
)

正如您所看到的,每次进行nbs循环,然后稍后再添加0时,您就会将repeat设置为1

看起来您希望将这些循环分开 - repeat直到完成信息计算,然后foreach打印出整个列表l_pt

按照目前的情况,我认为您每次只通过大l_pt循环向repeat添加一行信息,并且只打印foreach语句中的一个项目。

移动括号会给你这个:

(repeat (sslength js)
    ;;...
    (setq nbs 0)
    ;;...
)
(foreach n l_pt
    ;;...
    (setq nbs (+ 1 nbs))
)

您也可以将(setq nbs 0)置于重复循环之外。无论哪种方式都可能是最好的,这样就可以清楚地知道你正在做什么,并且没有必要将它初始化5次......

此外,这也说明了为什么明确区分变量赋值是个好主意。他们可能会在长(setq)语句结束时丢失:

;; Do this,
(setq sentence "This is one or more variable assignments."
      number 200)

;; or this,
(setq sentence "This is one or more variable assignments.")
(setq number 200)

;; not this.
(setq sentence "This is one or more variable assignments." number 200)

无论如何,这些选项中的任何一个都应该让你的计数器nbs再次运作。

希望有所帮助!

P.S。只是为了帮助上述评论中的(+1 nbs)讨论,以下内容在AutoLISP中都是正确且等效的:

(+ 1 nbs)
(+ nbs 1)         ;; Order is not important for addition
(+ nbs 1 0 0 0)   ;; Any number of values can be added
(1+ nbs)          ;; The typical way to increment a value
                  ;; (1+ is a function that returns the value + 1)

答案 1 :(得分:0)

它必须是AutoLISP特有的东西。我这样说是因为这段代码(适用于Common Lisp,你会看到)

(defun foo (l_pt)
  (let ((str_sep ";")
        (nbs 0))

    (mapcar #'(lambda (n) (write-line (strcat (list "sommet" str_sep
                                                    (itoa (setq nbs (+ 1 nbs))) str_sep
                                                    (rtos (car n) 2 2) str_sep
                                                    (rtos (cadr n) 2 2) str_sep
                                                    (strcat "2") str_sep
                                                    (strcat "borne")))
                                      ))
            l_pt)))

(defun rtos (a b c) (strcat a))

(defun strcat (string-designators)
  (with-output-to-string (strcat)
    (cond ((listp string-designators)
           (mapcar #'(lambda (s) (princ s strcat)) string-designators))
          (t (princ string-designators strcat)))))

(defun itoa (i) (write-to-string i))

表达式:

(foo '((x y) (a b) (aa bb)))

生成此输出:

sommet;1;X;Y;2;borne
sommet;2;A;B;2;borne
sommet;3;AA;BB;2;borne

不可否认,我不得不改变很多东西来容纳不在Common Lisp中的AutoLISP元素,也许最重要的是我没有写出相当于foreach的东西(因为没有办法知道我是复制它的特性),但至少看起来setq正在做你期望的事。