Câu trả lời:
Chúng tôi có một số tùy chọn có sẵn.
Bạn có thể catch/ throwđể thoát khỏi chức năng.
thí dụ:
(defun my-func ()
"thrown error"
(catch 'my-catch
(when t
(throw 'my-catch "always going to throw"))
(+ 42 1)))
Bạn cũng có thể sử dụng blockvà return-from(mặc dù bạn sẽ cần phải yêu cầu cl-macs)
thí dụ:
(require 'cl-macs)
(defun my-func ()
"block / return-from"
(block my-func
(when t
(return-from my-func))
(+ 42 1)))
Chúng ta cũng có cl-defunmột hàm ẩn blockcó cùng tên với hàm, vì vậy chúng ta có thể thực hiện blockkiểu với ít hơn.
thí dụ:
(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-defuncũng có sẵn như một bí danh defun*được định nghĩa trong cl.el:
(require 'cl)
(defun* my-func ()
"defun* implicit block"
(when t
(return-from my-func)) ; my-func is an implicit block.
(+ 42 1)))
Ngoài những gì @EmacsFodder bảo hiểm, chỉ cần đưa ra một lỗi.
Điều này sẽ không hữu ích nếu mã được gọi bên trong (một cách linh hoạt, không phải từ vựng) phạm vi của các cấu trúc xử lý lỗi như ignore-errorshoặc condition-case, nhưng nếu không thì đó là một cách tốt để thoát khỏi hàm. Đó là thực tế những gì được thực hiện hầu hết thời gian.
(defun my-func ()
"..."
(unless something (error "Whoops!"))
; continue as usual...
(+ 42 1))
Nếu bạn muốn tự xử lý lỗi thì bạn có thể đặt mã cuộc gọi (ví dụ như cuộc gọi đến một cái gì đó mà gọi my-funcmột cách sâu sắc ) bên trong a condition-case. Một lần nữa, đây là những gì được thực hiện hầu hết thời gian, ít nhất là thường xuyên như sử dụng catch+ throw. Tất cả phụ thuộc vào hành vi bạn muốn.
catch, sau đó unwind-protect, condition-casevà tương tự là hữu ích. Có cả một phần của hướng dẫn Elisp dành cho lối thoát hiểm không nhắm mục tiêu . (Và không có gì đặc biệt về bất kỳ ai trong số họ, IMO.)
catch/throwcó nhiều thành ngữ hơn trong elisp, vì các cách tiếp cận khác cuối cùng được thực hiện theo cách bắt / ném. Hướng dẫn elisp nói: "Hầu hết các phiên bản khác của Lisp, bao gồm Common Lisp, có nhiều cách chuyển kiểm soát nonsequentially:return,return-from, vàgo., Ví dụ Emacs Lisp chỉ cóthrow."