使用 Lisp 将新元素推入新的空列表

Pushing new elements into a new empty list using Lisp

下面的函数尝试更新 *features-list* 元素特征。 feature-list 定义为全局变量。

当我 运行 函数针对空 *feature-list* 时,我收到一条错误消息

The object is a CONDITION of type TYPE-ERROR.
DATUM: NIL
EXPECTED-TYPE: CONS

然而,当我初始化 *feature-list* 时,该函数正确执行。

(defun update-feature-list (feature)
  (let ((feature-index))
    (setq feature-index (position feature *features-list*))
    (cond ((equal feature-index nil) 
           (push feature (cdr (last *features-list*)))
           (setq feature-index (position feature *features-list*))))))

使用标准格式。参见 http://www.gigamonkeys.com/book/syntax-and-semantics.html#formatting-lisp-code

(defun update-feature-list (feature)
  (let ((feature-index))
    (setq feature-index (position feature *features-list*))
    (cond ((equal feature-index nil)
           ;;case 1 If feature index ==nil ;;we need to add the feature 
           (push feature (cdr (last *features-list*)))
           (setq feature-index (position feature *features-list*))))))

只有一个子句的cond是没有意义的。我猜你的意思是 when,而且你 无论如何都想更新索引,我。 e.在条件之外。

(defun update-feature-list (feature)
  (let ((feature-index))
    (setq feature-index (position feature *features-list*))
    (when (equal feature-index nil)
      (push feature (cdr (last *features-list*))))
    (setq feature-index (position feature *features-list*))))

你不需要只为 return 设置局部变量:

(defun update-feature-list (feature)
  (let ((feature-index))
    (setq feature-index (position feature *features-list*))
    (when (equal feature-index nil)
      (push feature (cdr (last *features-list*))))
    (position feature *features-list*)))

您可以直接在 let 头部创建绑定:

(defun update-feature-list (feature)
  (let ((feature-index (position feature *features-list*)))
    (when (equal feature-index nil)
      (push feature (cdr (last *features-list*))))
    (position feature *features-list*)))

不要检查 equalnil,而是使用 null:

(defun update-feature-list (feature)
  (let ((feature-index (position feature *features-list*)))
    (when (null feature-index)
      (push feature (cdr (last *features-list*))))
    (position feature *features-list*)))

您可以内联该变量:

(defun update-feature-list (feature)
  (when (null (position feature *features-list*))
    (push feature (cdr (last *features-list*))))
  (position feature *features-list*))

而不是 nullposition,使用 notmember:

(defun update-feature-list (feature)
  (when (not (member feature *features-list*))
    (push feature (cdr (last *features-list*))))
  (position feature *features-list*))

列表中最后一个缺点的 cdr 不是您想要推送的地方 东西上。我猜你想要 append,但在大多数情况下,你应该 而是推到列表的前面,这样效率更高。 也有 pushnew 正是为了这个。返回新位置不 但是,现在很有意义:

(defun update-feature-list (feature)
  (pushnew feature *features-list*)
  (position feature *features-list*))

如果您确实需要此顺序和位置,请改用可调向量:

(defvar *features-list* (make-array 10
                                    :adjustable t
                                    :fill-pointer 0))

(defun add-feature (feature)
  (or (position feature *features-list*)
      (vector-push-extend feature *features-list*))) ; v-p-e returns the index

Joshua Taylor 提供的解决方案。

Your approach to "push some val to a list inside a function" approach doesn't work; what happens if the original list is empty? You can't modify the car or cdr of the empty list; it doesn't have those. That said, if you do want to use the approach you described, you might do it a little more clearly with (push newvalue (rest list)) (rotatef (first list) (second list)). (That's certainly not the only option, though.)