8

代码片段 1 和代码片段 2 有什么区别?

;CODE SNIPPET 1
(define i 0)                      
(do ()                             
  ((= i 5))                       ; Two sets of parentheses
  (display i)                     
  (set! i (+ i 1))) 


;CODE SNIPPET 2
(define i 0)                      
(do ()                             
  (= i 5)                         ; One set of parentheses
  (display i)                     
  (set! i (+ i 1))) 

第一个代码片段产生 01234,第二个产生 5。这是怎么回事?额外的一组括号有什么作用?另外,我看到[(= i 50)]used 而不是((= i 5)). 有区别吗?谢谢!

4

2 回答 2

16

do 形式的一般结构是这样的:

(do ((<variable1> <init1> <step1>)
     ...)
    (<test> <expression> ...)
  <command> ...)

解释http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-ZH-6.html#node_chap_5,每次迭代都从评估开始<test>,如果评估为真值,<expression>则从左侧评估 s向右,最后一个值作为do表单的结果返回。在您的第二个示例=中,将被评估为布尔值,意思是 true,然后 i 将被评估,最后 5 是表单的返回值。第一种情况(= i 5)是测试,do表单返回一个未定义的值。编写循环的通常方法更像是这样:

(do ((i 0 (+ i 1)))
    ((= i 5) i)      ; maybe return the last value of the iteration
  (display i))

您不需要循环变量的显式突变,因为这是由<step>表达式处理的。

于 2010-07-07T23:08:21.213 回答
6

在第一种情况下,((= i 5))用作终止测试。所以重复do循环直到i = 5。

在第二种情况下, (= i 5) 不是测试。do 循环只执行第一种形式,它返回5

--

(根据所附评论)括号在方案的某些方言中是可以互换的。有时将 [] 用于参数(即对父对象do)被认为是惯用的。

于 2010-07-07T22:18:54.910 回答