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 を生成し、2 番目のコード スニペットは 5 を生成します。何が起こっているのでしょうか? 余分な括弧のセットは何をしますか? [(= i 50)]また、の代わりに使用されているのを見たことがあり((= 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フォームの結果として返されます。2 番目の例=では、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))は終了のテストとして機能します。したがって、i = 5 になるまで do ループが繰り返されます。

2 番目のケースでは、(= i 5) はテストではありません。do ループは単純に最初のフォームを実行し、 5 を返します

--

(添付のコメントによると)ブラケットは、スキームのいくつかの方言で交換可能です。[] をパラメーターに使用することは慣用的であると見なされることがあります (つまり、親のdo に対して)。

于 2010-07-07T22:18:54.910 に答える