構造体を作成する - lisp-cookbook-ja/common-lisp GitHub Wiki

構造体

構造体を作成する

構造体を定義するには、 defstruct を利用します。 defstruct には多様なオプションがありますが、最も簡単な定義は下記の様になるでしょう。

(defstruct person
  name age tall)

;; 中身を観察する
(describe (make-person))
;-> #S(PERSON :NAME NIL :AGE NIL :TALL NIL)
;   Type: PERSON
;   Class: #<STRUCTURE-CLASS PERSON>
;   NAME: NIL
;   AGE: NIL
;   TALL: NIL

defstruct で上記の様に定義するとコンストラクタとして make-person 、アクセサとしてperson-name、person-age、person-tallも定義されます。アクセサは setf 可能です。(この振舞いは定義時のオプションで変更できます。) コンストラクタにはスロットの名前がキーワードで指定でき、指定した値が初期値となります。

(make-person :name "春夫" :age 20 :tall 172.5)
;=> #S(PERSON :NAME "春夫" :AGE 20 :TALL 172.5)

アクセサ使用例

(let ((p (make-person :name "春夫" :age 20 :tall 172.5)))
  (format t "~Aさんは~D歳で、身長は~Fセンチあります。~%" (person-name p) (person-age p) (person-tall p)))
;-> 春夫さんは20歳で、身長は172.5センチあります。
;=> NIL

 ;; 初期値は指定せず後で設定
(let ((p (make-person)))
  (setf (person-name p) "春夫"
        (person-age p) 20
        (person-tall p) 172.5)
  (format t "~Aさんは~D歳で、身長は~Fセンチあります。~%" (person-name p) (person-age p) (person-tall p)))
;-> 春夫さんは20歳で、身長は172.5センチあります。
;=> NIL

尚、ANSIの仕様では slot-value が構造体で使えるかどうかは、処理系の判断に任せていますが、大抵の処理系では slot-valuewith-slots が構造体でも使えるようです。(Allegro CL、SBCL、LispWorks等々)

(let ((p (make-person :name "春夫" :age 20 :tall 172.5)))
  (with-slots (name age tall) p
    (format t "~Aさんは~D歳で、身長は~Fセンチあります。~%" name age tall)))
;-> 春夫さんは20歳で、身長は172.5センチあります。
;=> NIL