从when语句中的函数返回 [英] Returning from a function inside when statement
问题描述
我要做的就是使用when语句返回一个值:( 我想要以下功能:
All I'm trying to do is use a when statement to return a value :( I want the functionality of:
if(x)
return y
我正在尝试使用:
(when (x) y)
但是,when语句的求值方式不会退出函数并返回y.它只是愉快地进行到下一行.有没有一种方法可以在不制作看起来非常难看的if-else块的情况下进行此操作? mzscheme/racket不允许使用1臂ifs.
But the when statement is not evaluating in a way that exits the function and return y. It just happily carries on to the next line. Is there a way to do this without making an extremely ugly looking if-else block? mzscheme/racket does not allow 1-armed ifs.
推荐答案
您已将其标记为Common Lisp和Racket,这是两种完全不同的语言.如果您使用的是Racket或Scheme,并且想尽早从某个函数返回,则可以使用延续:
You tagged this as both Common Lisp and Racket, which are two completely different languages. If you're using Racket or Scheme and want to return from a function early, you can do it using a continuation:
(define (my-function x y)
(call-with-current-continuation
(lambda (return)
(when x (return y))
;; Rest of code not evaluated if X is true
)))
在包括Racket在内的某些Scheme实现中,call-with-current-continuation
也绑定到call/cc
,但是call-with-current-continuation
是使用延续的唯一可移植方式.
In some Scheme implementations including Racket, call-with-current-continuation
is also bound to call/cc
, but call-with-current-continuation
is the only portable way to use continuations.
以上内容比使用cond
语句还要难看.如果要消除所有多余的废话,可以定义一个宏,该宏创建define
的替代版本,该版本自动创建延续并将其绑定到return
:
The above is even uglier than using a cond
statement. If you want to get rid of all that extra crap, you can define a macro that creates an alternate version of define
that automatically creates the continuation and binds it to return
:
(define-syntax define/return
(syntax-rules ()
((_ (name . args) . body)
(define (name . args)
(capture-vars (return)
(call/cc (lambda (return) . body)))))))
这需要您拥有我的capture-vars
宏,您可以在此答案中找到.
This requires you to have my capture-vars
macro, which you can find in this answer.
Leppie 提供了define/return
的以下实现,它更简单,因为它不需要我的capture-vars
宏:
Leppie provided the following implementation of define/return
which is much simpler since it doesn't require my capture-vars
macro:
(define-syntax define/return
(lambda (x)
(syntax-case x ()
[(_ (name . args) . body)
(with-syntax
([return (datum->syntax #'name 'return)])
#'(define (name . args)
(call/cc (lambda (return) . body))))])))
但是,如果将define/return
合并到另一个宏中,则很容易意外地取消捕获return
的定义,以这种方式进行.
EDIT 2: However, it's easy to accidentally un-capture the definition of return
doing it this way, if you incorporate a define/return
in another macro.
然后return
的行为将与您期望的一样,并且不会在语法上令人讨厌:
Then return
will behave as you'd expect and not be syntactically repugnant:
(define/return (my-function x y)
(when x (return y))
;;; more code...
)
但是,如果您使用Common Lisp,情况就不同了.在Common Lisp中,只有定义了名为nil
的block
时,(return y)
才会编译.某些形式隐式定义了一个名为nil
的块,例如loop
宏.如果没有名为nil
的块,您仍然可以使用return-from
从命名的块返回.如果您在用defun
定义的函数中,则该函数的名称也是包装该函数的块的名称,因此可以使用:
However, if you're using Common Lisp, the situation is different. In Common Lisp, (return y)
will only compile when a block
named nil
is defined. Certain forms implicitly define a block named nil
, such as the loop
macro. Without a block named nil
, you can still use return-from
to return from a named block. If you're in a function defined with defun
, the name of that function is also the name of a block that wraps that function, so this would work:
(defun my-function (x y)
(when x (return-from my-function y))
;;; more code
)
这篇关于从when语句中的函数返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!