2016-07-31 58 views
0

我可以在球拍使用“而”循环与代码While Loop Macro in DrRacket从环球拍使用break

(define-syntax-rule (while-loop condition body ...) 
    (let loop() 
    (when condition 
     body ... 
     (loop)))) 

不过,我想用一个无限循环内线突破如下:

(define (testfn) 
    (define x 5) 
    (while-loop #t   ; infinite while loop; 
    (println x) 
    (set! x (sub1 x)) 
    (when (< x 0) 
     (break))))   ; HOW TO BREAK HERE; 

如何在上面的无限循环中插入break?感谢您的评论/答复。

+1

在问题的代码使用一个命令行式风格,这不是我们如何写在方案一环。 –

回答

3

你不知道。球拍在Scheme系列中,因此所有的循环实际上都是通过递归完成的。

通过不递归,您摆脱了循环。任何其他值都将成为表单的结果。

(define (helper x) 
    (displayln x) 
    (if (< x 0) 
     'return-value 
     (helper (sub1 x))) 
(helper 5) 

有宏使得语法更简单。使用命名let是:

(let helper ((x 5)) 
    (displayln x) 
    (if (< x 0) 
     'return-value 
     (helper (sub1 x))) 

看着你while-loop只是使用命名let宏变成了递归程序的宏。

如果你不用#t写一个表达式,最终会变成假,它停止。像:

(while-loop (<= 0 x) 
    ...) 

注意,使用set!以更新循环变量不被认为是很好的做法。如果您正在学习球拍,请尽量不要使用set!或您的新循环结构。尝试使用名为letletrec

2

正如在链接问题的接受答案中提到的,它是而不是推荐 - 根本!以这种方式循环。使用标准方案时避免使用命令循环并优先递归(使用助手程序或名为let),或在球拍中使用iterations and comprehensions。并且,break不是标准的Scheme构造。考虑使用更地道球拍,不需要明确的断裂,避免了命令行式风格重写逻辑:

(define (testfn n) 
    (for [(x (in-range n -1 -1))] 
    (println x))) 

(testfn 5) 
=> 5 
    4 
    3 
    2 
    1 
    0