임의의 지점에서 함수에서 어떻게 돌아 옵니까?


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)))

즐거움 *

cl-defun다음과 같이 defun*정의 된 별칭으로도 사용할 수 있습니다 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 측면에서 구현되므로 catch/ throw는 더 관용적입니다. elisp 매뉴얼은 말한다 : "CL의 포함 리스프의 대부분의 다른 버전, 비 순차적으로 제어를 전송하는 여러 가지 방법이 있습니다 return, return-from하고 go. 예를 들어, 이맥스 리스프는있다 throw."
— phils

5

@EmacsFodder가 다루는 것 외에도 오류가 발생합니다.

코드가 ignore-errorsor 와 같은 오류 처리 구문의 범위 내에서 (동적으로, 어휘 적으로) 호출되지 않으면 도움이되지 condition-case않지만 그렇지 않으면 함수를 종료하는 좋은 방법입니다. 실제로 대부분의 시간이 수행됩니다.

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

오류를 직접 처리하려면 호출 코드 (예 : 울리게 호출하는 것에 대한 호출 my-func)를 안에 넣을 수 있습니다 condition-case. 다시 말하지만, 이것은 적어도 catch+ 를 사용하는 것만 큼 자주 수행됩니다 throw. 그것은 당신이 원하는 행동에 달려 있습니다.


답변 Drew에게 감사드립니다. 나는 이것이 일반적인 방법이라는 데 동의합니다. 그러나 다른 많은 언어로 조기에 복귀 한다고해서 오류를 처리해야하는 복잡성 이 발생하지는 않습니다 . 질문 / 응답 세트를 조사 할 때. 나는 항상 나에게 기분이 좋지 않은 "오류"스타일에 대한 대안을 찾고 있었다. 질문 텍스트에 명시 적으로 지정하지 않았습니다.
— ocodo

1
그것은 모두 당신이하고 싶은 것에 달려 있습니다. 추가 처리 / 처리없이 즉시 종료하려면 Emacs에서 오류를 발생시키는 것이 로컬이 아닌 종료로가는 좋은 방법입니다. 당신은 즉, 로컬이 아닌 종료하는 동안 뭔가를 할 경우, 어떤 방법으로 그것을 처리 catch, unwind-protect, condition-case그리고처럼 유용하다. 비 로컬 이탈 에 대한 Elisp 매뉴얼의 전체 섹션 이 있습니다. (그리고 IMO에 대해서는 특별히 별다른 문제는 없습니다.)
— Drew

"느낌"은 전적으로 주관적입니다. 로컬이 아닌 수동 참조에 감사드립니다.
— ocodo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.