在Racket中使用break from loop

时间:2016-07-31 15:38:19

标签: scheme racket

我可以使用While Loop Macro in DrRacket

中的代码在Racket中使用“while”循环
(define-syntax-rule (while-loop condition body ...)   
  (let loop ()
    (when condition
      body ...
      (loop))))

但是,我想在无限循环中使用break,如下所示:

(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?感谢您的意见/答案。

2 个答案:

答案 0 :(得分:3)

你不是。 Racket在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写一个最终变为false的表达式,它就会停止。像:

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

请注意,使用set!更新循环中的变量不被视为良好做法。如果您正在学习Racket,请尽量不要使用set!或新的循环结构。尝试使用已命名的letletrec

答案 1 :(得分:2)

正如联系问题的已接受答案中所提到的那样,推荐 - 根本没有!以这种方式循环。使用标准Scheme时,请避免使用命令式循环并优先使用递归(使用帮助程序或命名let),或在Racket中使用iterations and comprehensions

此外,break不是标准的Scheme结构。考虑使用更加惯用的Racket重写逻辑,不需要明确的破解并避免使用命令式:

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

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