我目前正在尝试编写一个函数,以十进制返回列表的平均值。
(defun calc-list-average (lst)
(float (/ (apply '+ lst) (length lst))))
Run Code Online (Sandbox Code Playgroud)
当我像这样调用函数时,一切正常:
(defvar *a-lst* '(5 6 1 3 6 7))
(princ (calc-list-average *a-lst*))
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用动态生成的列表调用该函数时,我收到错误“给 + 的参数列表被打点(由 WUERFEL-ERGEBNIS 终止)”
(let ((wuerfel-seiten 6) (wuerfel-ergebnis ()))
(loop
(let ((menu-option (get-option)))
(cond ((eql menu-option 1)
(princ "Bitte geben Sie die Anzahl der Wuerfelseiten ein: ")
(setq wuerfel-seiten (read)))
((eql menu-option 2)
(princ "Bitte geben Sie die Anzahl der Wuerfelwuerfe ein: ")
(let ((wuerfel-wuerfe (read)))
(setq wuerfel-ergebnis (get-random-list wuerfel-seiten wuerfel-wuerfe))))
((eql menu-option 3)
(write-line "Wuerfelauswertung")
(princ (calc-list-average 'wuerfel-ergebnis))) ; <-- error is raised here
((eql menu-option 4)
(exit))))))
Run Code Online (Sandbox Code Playgroud)
函数 get-option 只是将菜单打印到控制台并返回用户写入控制台的任何内容。get-random-list 返回一个列表并使用 (cap number-of-element) 调用。
当您调用 时calc-list-average,您传递的是符号 wuerfel-ergebnis(基本上是变量的名称)而不是该符号的值。将呼叫更改为
(calc-list-average wuerfel-ergebnis)
Run Code Online (Sandbox Code Playgroud)
也就是说,删除之前的引号wuerfel-ergebnis。引用的意思是“不要评估接下来的内容”。但您确实想评估符号wuerfel-ergebnis以获取其值。
以下是错误“给定的参数列表+被加点”的解释。该函数apply需要一个列表。在 Lisp 中,列表要么是空列表()(也可以写成nil),要么是cons列表的第一个元素和列表的其余部分的 a。例如'(1 2 3)相当于(cons 1 (cons 2 (cons 3 ()))). 在适当的列表中,当您按照cons调用的右侧进行操作时,您最终会到达()。如果您使用cons不同的方式,您可能会构建一个不正确的 list,其中cons调用的右侧会到达一些不是 的东西()。构建不正确列表的语法糖在尾随的非 nil 值之前使用一个点:(1 2 . "a")等价于(cons 1 (cons 2 "a"))。所以“dotted list”是“improper list”的别称。A(非零)符号 likewuerfel-ergebnis是不正确列表的特殊情况,您在下降 0 后到达末尾cons 调用。