2016-09-27 71 views
0

以下函數嘗試更新*features-list*使用元素特徵。 功能列表被定義爲全局變量。使用Lisp將新元素推入新的空列表

當我運行對空*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*)))))) 
+1

請修復您的代碼 - 縮進和括號。現在是不可讀的。 – sds

+0

是的..關於什麼可能導致錯誤的任何想法? – ijuio

+0

請參閱[此評論](http://stackoverflow.com/questions/34793011/push-doesnt-modify-the-list-being-a-function-argument#comment57330915_34793011)。 –

回答

1

解決方案通過this comment約書亞·泰勒提供。

您的「將某些val推入函數列表中」方法 不起作用;如果原始列表爲空,會發生什麼情況?你不能 修改汽車或cdr的空白列表;它沒有那些。 表示,如果您確實想要使用您描述的方法,那麼您可以使用(push newvalue (rest list))(rotatef (first list) (second list))更清楚一點來做 。 (這當然不是唯一的選擇, 雖然)。

3

使用標準格式。見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*)))))) 

A cond一個條款是沒有意義的。我想你的意思是when,而你 想在任何情況下更新索引,我。即條件之外。

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

你並不需要設置一個局部變量只是回到它:

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

而不是檢查equal ... nil,使用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*)) 

而不是null ... position,使用not ... member

(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 
+0

謝謝...但是,我確實需要這個元素的確切順序..所以我不能推入列表的開頭...我試着上面的代碼更正..隨着推,以及append..and都有相同的行爲..當列表是空的時候出錯,nd當初始化時有適當的行爲至少有一個元素.. – ijuio

+0

因此,當我使用append的後綴名push..and初始化列表(defparameter * features_list * nil)而不是我曾經初始化爲(defparameter * featuteres_list *'())它正常工作..使用推,只要列表是獨立的,它是如何初始化的空,錯誤仍然存​​在。對我來說,我我很高興現在用這個append for this ..但是如果有人可以解釋爲什麼push按照這種方式在空列表上運行,那將會很棒 – ijuio

+0

@ijuio:'(push'foo * list *)'和'(setf * list *(cons'foo * list *))'。 '(list'a'b'c)'與'(cons'a(cons'b(cons'c nil)))'相同。這就是列表在Lisp中的工作方式:它們是一個cons鏈。當你的變量被綁定到一個列表時,它實際上是指「第一個」或「最外面的」cons單元。 'Last'返回最後或「最內層」的缺陷單元。 '無'不是一個缺點,而是一個原子,它也被用作空列表。 – Svante