【问题标题】:How to increment a variable in Lisp如何在 Lisp 中增加一个变量
【发布时间】:2016-07-13 16:31:50
【问题描述】:

这是代码中的问题:

    (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)

我在输出中有这些类型的文件:

索梅茨;;

类型;编号;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

【问题讨论】:

  • (+ 1 nbs) 是否与(+1 nbs)完全相同的事情?
  • Lisp 家族语言中的表单一般写成(operator arg1 arg2 ...)。在赋值运算符setq 的情况下,自变量顺序为(setq <place> <new value>)。这意味着(setq (nbs (+1 nbs))) 是错误的,应该是(setq nbs (+ 1 nbs))
  • 很好,@Joshua。当你习惯了在() 中使用函数参数的语言时,很容易错过这种事情。您可能想将其发布为答案。 (顺便说一句,+1 可能是一个已定义的增量函数,(+1 nbs) 返回与(+ 1 nbs) 相同的值。但后一种形式显然是正确的。)
  • @Feldur 当然,这里是:link
  • 你能检查一下像这样的最小示例会发生什么吗? (defun test (/ counter) (foreach n '(a b c) (write-line (itoa (setq counter (+ 1 counter))))))

标签: lisp autolisp


【解决方案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))
    )
)

如您所见,您每次通过 repeat 循环时都将 nbs 设置为 0,然后稍后将 1 添加到它。

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

就目前而言,我认为您每次通过 repeat 大循环仅将 1 行信息附加到 l_pt,并且仅打印 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 再次工作。

希望有帮助!

附:只是为了帮助上述 cmets 中的 (+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)

【讨论】:

    【解决方案2】:

    它一定是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
    

    诚然,我不得不更改很多东西以适应 AutoLISP 中不在 Common Lisp 中的元素,其中最重要的可能是我没有编写与 foreach 等效的内容(因为无法知道我会复制它的特质),但至少看起来setq 正在做你期望的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-03
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多