任意のポイントで関数からどのように戻りますか?


12

関数が終了する前に、どのようにして関数から早期に戻りますか?例えば:

(defun my-func () 
 "for example."
 (unless something (return nil))
 ; continue as usual...
 (+ 42 1))

回答:


19

利用可能な多くのオプションがあります。

スロー

catch/でthrow機能を終了できます。

例:

(defun my-func ()
  "thrown error"
  (catch 'my-catch
    (when t
      (throw 'my-catch "always going to throw"))
    (+ 42 1)))

ブロック

使用することもできますblockし、return-from(あなたが必要とする必要がありますがcl-macs

例:

(require 'cl-macs)

(defun my-func ()
  "block / return-from"
  (block my-func
    (when t
      (return-from my-func))
    (+ 42 1)))

cl-defun

また、関数と同じ名前cl-defunを持つ暗黙的なものも持っているblockためblock、より少ないスタイルでスタイルを実行できます。

例:

(require 'cl-macs)

(cl-defun my-func ()
  "cl-defun implicit block"
  (when t
    (return-from my-func)) ; my-func is an implicit block.
  (+ 42 1)))

defun *

cl-defundefun*定義されているエイリアスとしても利用可能ですcl.el

(require 'cl)

(defun* my-func ()
  "defun* implicit block"
  (when t
    (return-from my-func)) ; my-func is an implicit block.
  (+ 42 1)))

4
CL構文を好まない場合、catch/ throwはelispではより慣用的であることに注意してください。他のアプローチは最終的にcatch / throwの観点から実装されます。elispのマニュアルは言う:「Common Lispのを含めたLispの他のほとんどのバージョンは、非逐次的に制御を移すのいくつかの方法がありますreturnreturn-fromgo。例えば、Emacs Lispには、唯一持っていますthrow。」
phils

5

@EmacsFodderの対象に加えて、エラーを発生させてください。

これは、ignore-errorsまたはなどのエラー処理構文の範囲内で(動的に、字句的にではなく)コードが呼び出された場合には役に立ちませんcondition-caseが、そうでなければ関数を終了するための素晴らしい方法です。実際、ほとんどの場合に行われます。

(defun my-func () 
 "..."
 (unless something (error "Whoops!"))
 ; continue as usual...
 (+ 42 1))

自分でエラーを処理したい場合は、呼び出しコード(たとえば、最終的に呼び出すものへの呼び出しmy-func)をに入れることができますcondition-case。繰り返しますが、これはほとんどの場合、少なくともcatch+ を使用するのと同じくらい頻繁に行われthrowます。それはすべてあなたが望む行動に依存します。


ドリューの答えをありがとう、これは非常に一般的な方法であることに同意します。ただし、他の多くの言語で早期に返品するだけで、エラーを処理する複雑さが生じません。質問/回答セットを調査するとき。私はいつも私にとっていつも気味の悪い「エラーアウト」スタイルに代わるものを探していました。質問テキストでこれを明示的に指定しませんでした。
オコド

1
それはすべてあなたが何をしたいかに依存します。Emacsで、これ以上処理や処理をせずにすぐに終了したい場合は、エラーを発生させることが非ローカルな出口に行く良い方法です。あなたは非ローカルの終了時に何かをしたい場合は、すなわち、その後、何らかの方法でそれを処理しcatchunwind-protectcondition-caseなどが便利です。Elispマニュアルには、非ローカル出口に特化したセクションがあります。(特に、IMO、それらのいずれかについてクルージは何もありません。)
ドリュー

もちろん、「感じ」は完全に主観的なものです。非ローカルマニュアルrefをありがとう。
オコド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.