2

mutator elisp 関数を定義するにはどうすればよいですか? つまり、関数外で使用するために関数内で変更できる elisp 関数にパラメーターを送信するにはどうすればよいですか (C++ の非 const 参照変数またはポインターに似ています)。たとえば、次のように定義された関数 foo があるとします。

(defun foo (a b c d)
  ;do some stuff to b, c, and d
        .
        .
        .
  )

私はそれを次のように呼びたいと思うかもしれません

(defun bar (x)
  (let ((a) (b) (c) (y))
  .
  .
  .
        ;a, b and c are nil at this point
        (foo x a b c)
        (setq y (some-other-function-of a b c x and-other-variables))
  .
  .
  .
)) ... ) 
  y)

ある関数にローカルなすべてのパラメーターを 1 つの大きな古いリストに入れ、関数の最後でリストを評価し、その関数の戻り値 (リストの)、つまり

(setq return-list (foo read-only-x read-only-y))
(setq v_1 (car return-list))
(setq v_2 (cadr return-list))
            .
            .

しかし、より良い方法はありますか?これを解決するためにこれまでに達成したことは、変数が渡された方法と変わらない変数で関数を終了することだけです

なぜこれをやりたいのかというと、私は単純に、いくつかの名前付け可能な概念 c に関連する式のすべてのコレクションが独自の小さなモジュール c_1、c_2、c_3、... c_n に存在するように、いくつかの大きな関数 F をリファクタリングしようとしています。途中で更新する必要がある引数を指定して、F 内から呼び出すことができます。つまり、F は次のようになります。

(defun F ( ... )
  (let ((a_1) (a_2) ... )
    (c_1 a_1 ... a_m)
    (c_2 a_h ... a_i)
     .
     .
     .
    (c_n a_j ... a_k)
     .
     .
     .
 ))...))
4

2 に答える 2

2

私が考えることができる2つの方法:

  • 「関数」foo を関数ではなくマクロにする (可能であれば)
  • 新しく作成されたコンス (またはそれらの複数) を関数に渡し、それらの car と cdr を setcar/setcdr 経由で置き換えます。

関数が複雑すぎる場合は、両方のアプローチを組み合わせることもできます。マクロ foo を使用して、a と b のコンスを作成し、そのコンスで関数 foo0 を呼び出し、後で car と cdr を再度アンパックします。

2 つ以上の引数が必要な場合は、複数のコンスをパラメーターとして使用してください。

于 2013-06-29T11:10:37.353 に答える
0

どうすればできるかをお見せするだけですが、やらないでください。スタイルが悪いからです。

(defun set-to (in-x out-y)
  (set out-y in-x))

(let (x)
  (set-to 10 'x)
  x)

ただし、これが機能しない場合があります。

(let (in-x)
  (set-to 10 'in-x)
  in-x)

このC++コードに少し似ています

void set_to(int x, int* y) {
    *y = x;
}

int y;
set_to(10, &y);

実際には、C++ に非 const 参照がないようにして、上記のように各ミューテーターをポインターで呼び出す必要があることを望みます。

繰り返しますが、本当に必要でない限り実行しないでください。代わりにまたはを使用します。multiple-value-bindcl-flet

于 2013-07-22T15:47:20.553 に答える