如何在 Racket 中使用 let 继续下一次迭代?

How to continue to the next iteration using let in Racket?

我正在尝试修改下面的代码,以便当 (when (= i 6) (loop (+ 1 i))) 出现时循环移动到下一次迭代而不继续执行“做事”部分。

(let loop ([i 0])
  (cond
    [(= i 10) (printf "end\n")]
    [else
     (when (= i 6) (loop (+ 1 i)))
       (define x (+ 1 2)) ; do stuff
       (printf "~a\n" i)
       (loop (+ 1 i))]))

基本上我想要获得的是类似于 C# 中的“continue”的东西(就像下面的代码),但是在 Racket 中使用 let:

for (int i = 0; i < 10; i++) 
{
    if (i == 6) 
    {
        continue;
    }
    Console.WriteLine(i);
}    

如果这在 Racket 中不可能(或不推荐),我可以使用什么作为替代方案?

您可以通过向 cond 表达式添加一个额外的 case 来获得所需的效果。这等同于您的 C# 示例:

(let loop ([i 0])
  (cond [(= i 10) (printf "end\n")]
        [(= i  6) (loop  (add1 i))]
        [else
         ; do some other stuff
         (printf "~a\n" i)
         (loop (add1 i))]))

您可以在每个条件之后“做一些事情”,只要最后一个表达式是递归的出口或递归调用 - 请记住,只会返回最后一个表达式的值,如果您需要将值传递给下一次迭代,您需要将参数添加到递归调用中。

通过否定条件重写 continue

for (int i = 0; i < 10; i++) 
{
    if (i != 6) 
    {
        Console.WriteLine(i);
    }
}    

然后作为 while 而不是 for:

int i = 0;
while (i < 10) 
{
    if (i != 6) 
    {
        Console.WriteLine(i);
    }
    i += 1;
}    

然后这具有几乎完全相同的形式:

(let loop ([i 0])
  (when (< i 10)
    (unless (= i 6)
      (printf "~a\n" i))
    (loop (+ 1 i))))