リスト自体をバインドせずに、リストから複数の値を直接バインドします


12

Emacs Lispの一時変数を経由せずに、変数に複数の戻り値を直接割り当てることは可能ですか?

たとえば、2つのリストのリストを返す関数があるとします。

(defun test-func ()
  (setq a '(a b))
  (setq b '(c d))
  `(,a ,b))

最初の戻り値をlist-aに、2番目の戻り値をに割り当てたい場合list-b、一時変数を使用してこれを行うことができます。temp例:

(let* ((temp (test-func)) (list-a (car temp)) (list-b (cadr temp)))
  (message-box (prin1-to-string list-a))
  (message-box (prin1-to-string list-b)))

これをもっと簡単に行うことは可能ですか?(私はあなたが一時変数を指定する必要がないPerlとPythonに慣れています)


2
cl-destructuring-bindマクロを試すことができます。また、あなたは本当にsetq内部で使用するつもりでしたdefunか?setq「特別な」(グローバルにアクセス可能な)変数を作成します。これは通常、関数の外側に置くものです(同じ変数を複数回宣言する意味はほとんどありませんが、関数は複数回実行することを意図しています)。
wvxvw

@wvxvwありがとう!はいlet、関数内で使用するのを忘れました。グローバル変数を設定する予定はありませんでした:)
HåkonHægland15年

回答:


8

Common Lispには複数の値という特別な機能があり、Emacs Lisp互換性ライブラリ はリストを使用してそれらをエミュレートします

したがって、あなたはできる

(defun test-fun ()
  (let ((a 1) (b 2))
    (cl-values a b)))

(cl-multiple-value-bind (a b) (test-fun)
  ...)

(ELのすべてのCL機能にプレフィックスをロードcl-libして使用しcl-ます)。

:上記のリンクされたSOの答えを見ると、MVをリストでエミュレートすることは、控えめに言っても準最適であることがわかります(以下の@Stefanのコメントも参照)。


multiple-value-bind代わりに使用する利点はありますかcl-multiple-value-bind(後者のみがマニュアルgnu.org/software/emacs/manual/html_node/cl/Multiple-Values.htmlに記載されているようです)?
ホーコンヘーグランド

3
@HåkonHæglandこれらは同じ機能ですが、後者を使用する必要があります。このclパッケージは、もはや使用されることを意図していません。cl-lib代わりに常にcl-プレフィックスを使用して関数を定義するパッケージを使用する必要があります
。– Malabarba

1
私はの使用に対してお勧めしますcl-values:それはCommonLispのの「ベストエフォート」エミュレーションのですvaluesが、それはないすべては(すなわち、それは嘘のようなものだ)リストを返しているので、それは本当に互換性はありませんし、私の経験の人々に遅かれ早かれ終わりますそれらをリストとして操作する(つまり、抽象化を破る):リストを明示的に使用する方が適切です(もし気に入らない場合はpcase-letcl-destructuring-bindではなくを使用してくださいcl-multiple-value-bind)。
ステファン

4

cl-lib互換性パッケージに依存することに加えて、Elispで推奨される方法は次のとおりですpcase

(defun test-fun
  (let ((a '(a b))
        (b '(c d)))
    `(,a ,b)))

(defun other-test-fun ()
  (pcase-let ((`(,a ,b) (test-fun)))
    (message "a = %s; b = %s" a b)))

他にpcase-let、そこにもだpcase-dolistpcase-lambdapcase自分自身。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.