2012-02-13 14 views
1

以下の変数にsetfを実行する適切な方法は何ですか?ループ内でのSetf構文の使用

CG-USER(279): (defun LETTERSEARCH (string1 string2) 
    (let ((newString nil)) 
    (let ((letterSearchOn nil)) 
    (loop for i from 0 below (length string1) 
     always 
      (setf (letterSearchOn (char string1 i))   
      (print letterSearchOn)))))) 
LETTERSEARCH 
CG-USER(280): (stringprod "abc" "abc") 

NIL 
Error: `(SETF LETTERSEARCHON)' is not fbound 
[condition type: UNDEFINED-FUNCTION] 
CG-USER(281): 
+0

このコードの意図を少し話せますか? 'newString'と' string2'のポイントは何ですか? – Inaimathi

+0

リスパーは通常、 CamelCaseではなく、別々の単語にハイフンを使用しています。 'newString'→' new-string'、 'letterSearchOn'→ ' letter-search-on'、... – Daimrod

答えて

5

これは(setf letterSearchOn (char string1 i))である必要があります。

方法は(setf)コモンリスプでは本当にクールです;それはマクロですが、使用されるマクロエクスパンダは引数に依存します。たとえば、

(defparameter a (list 1)) 
(setf (car a) 2) 
a ; => (2) 
(setf (cdr a) (list 3)) 
a ; => (2 3) 

奇妙に見えますか? (car a)は関数です...どうすれば新しい値に設定できますか?答えは、(setf)の最初の引数がcarで始まるリストである場合、コンスセルのcarを設定するコードに展開されます。最初の引数がcdrで始まるリストである場合、コンスセルのcdrを設定するコードに展開されます。

(setf)マクロを定義することもでき、(setf)は設定方法が分かる範囲を広げることができます。この場合、(letterSearchOn (char string1 i))を渡すので、特別なletterSearchOnマクロエクスパンダを使用したいと考えていますが、setfマクロエクスパンダが定義されていません。

+0

これは役に立ちますが、まだ私はまだ光を見ません。だから私はそれを(defparameter a(list 1))として宣言しますか?それで私はちょうどそれに1文字を保存したいので、それを(setf(car a)(list 0))として設定します。その後、その手紙が検索されます。 – Tequila

+0

@ JohnGabrielson、これは 'setf'の興味深いプロパティを示す単なる例でした。私の答えの最初の行で指摘したように、あなたの場合、不要な括弧のペアを削除するだけで済みます。 –

+0

ところで、文字列内の文字を繰り返し処理して印刷したい場合は、 '(string1のalways(print letterSearchOn)の間にあるletterSearchOnのループ) –

関連する問題