从when语句中的函数返回 [英] Returning from a function inside when statement

查看:83
本文介绍了从when语句中的函数返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要做的就是使用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中,只有定义了名为nilblock时,(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆