4

オブジェクト指向カウンターをプログラムする必要があります。最初に、関数 make-object はオブジェクト a と b を内部状態 0 でインスタンス化する必要があります。次に、「メソッド」:inc、:dec、および :res (増加、減少、リセット) が呼び出されます。次のようになります。

> (setq a (make-object) b (make-object))
...
> (funcall a :inc)
1
> (funcall a :inc)
2
> (funcall a :res)
0
> (funcall a :dec)
-1
> (funcall b :inc)
1

これまでの私のソリューションは次のようになります。

(defun make-object ()
  (let ((counter 0))
    (list #'(lambda () (incf counter))
          #'(lambda () (setf counter 0))
          #'(lambda () (decf counter)))))

(setq a (make-object) b (make-object))

a と b をインスタンス化でき、メソッドは次のように呼び出されます

(funcall (first a))
(funcall (second b))
(funcall (third a))

「first」の代わりに「:inc」を使用してメソッドを呼び出すために、次のことを試みました。

(defun myfuncall (var fun) 
  (funcall ((cond ((equal fun ":inc") first) 
                  ((equal fun ":res") second) 
                  ((equal fun ":dec") third)) 
            var)))

しかし、エラーがあります

While compiling MYFUNCALL :
In the form (#1=(COND ((EQUAL FUN ":inc") FIRST)
                      ((EQUAL FUN ":res") SECOND)
                      ((EQUAL FUN ":dec") THIRD))
             VAR), #1# is not a symbol or lambda expression.
   [Condition of type CCL::COMPILE-TIME-PROGRAM-ERROR]

誰でも私を助けてもらえますか?funcall に正しいことをさせるにはどうすればよいですか?


解決策を見つけました。

(defun make-object () 
  (let ((count 0))
    (lambda (msg)
      (case msg
        ((:inc) (incf count))
        ((:dec) (decf count))
        ((:res) (setq count 0))))))

これは私が望んでいたことをします。

4

1 に答える 1

3

それはほとんど機能しています。

(defun myfuncall (var fun) 
  (funcall ((cond ((equal fun ":inc") first) 
                  ((equal fun ":res") second) 
                  ((equal fun ":dec") third)) 
            var)))

とフォーム( ... )の周りに余分なものがあります。それを取り除く必要があります。CONDvar

またfirst、(etc) は変数参照になります。に電話する必要があります(first var)

それが機能するようになったら、別の方法でコードを書きたいと思うかもしれません。MAKE-OBJECT3 つの関数のリストではなく、単一の関数を返すとしたらどうでしょう。それはどのように機能しますか?

次の問題

((equal fun ":inc") 'first var)

上は無意味。FIRSTの結果に対して関数を呼び出したいとしますvar。これは関数を返し、それは 経由で呼び出されFUNCALLます。

于 2013-07-05T11:48:42.073 に答える