我要做的就是使用when语句返回一个值:(我想要以下功能:
if(x)
return y
我正在尝试使用:
(when (x) y)
但是when语句不是以退出函数并返回y的方式求值的。它只是愉快地进行到下一行。有没有一种方法可以在不制作看起来非常难看的if-else块的情况下进行此操作?mzscheme / racket不允许使用1臂ifs。
您将其标记为Common Lisp和Racket,这是两种完全不同的语言。如果您使用的是Racket或Scheme,并且想尽早从某个函数返回,则可以使用延续来实现:
(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
是使用延续的唯一可移植方式。
上面的内容比使用cond
语句还要丑。如果要消除所有多余的废话,可以定义一个宏,该宏创建替代版本的宏,该替代版本define
会自动创建延续并将其绑定到return
:
(define-syntax define/return
(syntax-rules ()
((_ (name . args) . body)
(define (name . args)
(capture-vars (return)
(call/cc (lambda (return) . body)))))))
这需要您具有我的capture-vars
宏,您可以在此答案中找到它。
编辑:Leppie提供了以下实现,define/return
它的实现要简单得多,因为它不需要我的capture-vars
宏:
(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))))])))
编辑2:但是,return
如果将a合并define/return
到另一个宏中,则很容易意外地取消捕获这样做的定义。
然后,return
将按照您的预期运行,并且不会在语法上令人讨厌:
(define/return (my-function x y)
(when x (return y))
;;; more code...
)
但是,如果您使用Common Lisp,情况会有所不同。在Common Lisp中,(return y)
仅当定义了block
named时才编译nil
。某些形式会隐式定义名为的块nil
,例如loop
宏。如果没有名为的块nil
,您仍然可以使用return-from
从已命名的块返回。如果您使用定义了一个函数defun
,则该函数的名称也是包装该函数的块的名称,因此可以使用:
(defun my-function (x y)
(when x (return-from my-function y))
;;; more code
)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句