2011-12-28 15 views
3

我有一個方案中的對象列表,如下所述。當例如從列表中取出第一個元素時,如何調用對象函數?方案:列表中的對象

(define persons false) 
(define length 10) 

(let loop ((n 0)) 
    (if (< n length) 
     (begin 
      (define newp (make-person)) 
      (send newp setage (- 50 n)) 

      (cond 
       ((= n 0) 
         (set! persons (list newp))) 
       (else 
         (set! persons (cons persons newp))) 
      ) 

      (loop (+ n 1)) 
     ) 
    ) 
) 

(define (firstpersonage) 
    (send (car persons) getage) 
) 

當調用第一個人員時,我收到錯誤消息,說沒有這樣的方法。有沒有辦法將第一個對象「投」成「人」類型?

謝謝!

+5

什麼是'化妝person'程序的執行情況? –

+1

考慮用數字0..9(可以用'(iota 10)'生成)替換你對'let loop'和'set!'的使用'map'。我知道這不是你問的,但我認爲這會讓你的代碼變得更短,更清晰。 – gcbenison

回答

2

首先,請學會indent Lisp正確。第二,你的問題在於你決定使用一堆副作用來構建Scheme中的人員列表(因此,你通過 列表構造的其中一個更精細的點絆倒了)。

我想在這種情況下做的是寫

(define persons 
    (map (lambda (n) 
     (let ((newp (make-person))) 
      (send newp setage (- 50 n)) 
      newp)) 
     (iota 10))) 

(define (firstpersonage) 
    (send (car persons) getage)) 

即,確定person是降年齡的十人,從50到41這樣做,這樣的列表避免了許多錯誤的可能性,包括你剛剛被咬過的那個。

如果你絕對,肯定不能忍受你的set! s到一部分,錯誤似乎是在該行

(set! persons (cons persons newp)) 

cons不追加兩個列表,它增加了一個新元素名單的頭。例如

(cons 3 (list 2 1)) => (3 2 1) 

如果以相反的方式做到這一點,你就不會完全得到你在找什麼

(cons (list 1 2) 3) => ((1 2) . 3) 
+0

在計劃中你應該使用地圖而不是mapcar,不是嗎? – Jonas

+0

@Jonas - Dammit,你說得對。我是現實生活中的常見Lisper,所以請原諒。 – Inaimathi

1

由於您使用cons的方法不對,您會收到錯誤信息;你沒有構建一個合適的列表。 (cons persons newp)創建一對新對,並將carnewp中的人員放入cdr,因此完成後,personscar中的內容不是其中的一個人對象。你可能會發現(cdr persons)是一個人物,但你可以做(send (cdr persons) getage)就好了。 (cdar persons)(cdaar persons)也是人物。所以它是一個列表,只有項目在cdr s和尾部在car s(直到你到達用(list newp)創建的初始列表,再次以其他方式)。

無論如何,如果你切換它,所以它去(cons newp persons)它應該工作。