foreach - 打破tcl中超过1层的foreach嵌套

标签 foreach tcl break

是否可以通过 1 个命令从两层嵌套退出?也就是说,假设我有以下代码:

foreach l { 1 2 3 4 } {
   foreach k { 3 4 5 6 } {
      if { $k > 4 } {
         break2
      } else {
         puts "$k $l"
   }
}

我希望看到的输出是:

1 3
1 4

问题是,如何编写break2(如果可能的话)?。
我不知道任何语言中都有这样的“功能”,除了将其包装在一个过程中,并使用 return 来停止proc,这更像是一种黑客行为,而不是正确的语言构造
谢谢。

最佳答案

直接做是不可能的; break 机制除了最近的循环上下文之外没有任何东西可以追踪。

处理此问题的最简单方法是使用 8.6 中的 try 和自定义异常代码(即 5 以上的任何值)。

foreach a {b c} {
    puts "a=$a; to show that this is not stopping the outermost loop"
    try {
        foreach l { 1 2 3 4 } {
            foreach k { 3 4 5 6 } {
                if { $k > 4 } {
                    # Generating a custom exception code is a bit messy
                    return -level 0 -code 5
                }
                puts "$k $l"
            }
        }
    } on 5 {} {
        # Do nothing here; we've broken out
    }
}

运行会给出以下输出:

a=b; to show that this is not stopping the outermost loop
3 1
4 1
a=c; to show that this is not stopping the outermost loop
3 1
4 1

But it's pretty messy to do this; the best approach is typically to refactor your code so that you can just return ordinarily to end the loop. Using apply might make this easier:

foreach a {b c} {
    puts "a=$a; to show that this is not stopping the outermost loop"
    apply {{} {
        foreach l { 1 2 3 4 } {
            foreach k { 3 4 5 6 } {
                if { $k > 4 } {
                    return
                }
                puts "$k $l"
            }
        }
    }}
}

使用 apply 的缺点是它是一个不同的变量上下文,并且有相当多的开销(因为所有堆栈帧管理)。不过,如果您小心的话,可以使用 upvar 解决变量上下文问题。

关于foreach - 打破tcl中超过1层的foreach嵌套,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33649662/

相关文章:

java - 为什么增强的 for 循环的局部变量必须是局部变量?

c# - 为了我们可以在其上放置 foreach,对集合的要求是什么?

tcl - Tcl 8.4 和 8.5 中的 keylset 错误?

tcl - 如何检查目录是否为空?

java - 使用 JOptionPane 时如何跳出 for 循环?

php - PHP 中 "break"或 "continue"之后的数字是什么意思?

php - PHP中foreach生成数组并返回会导致CPU利用率增加

javascript - 尝试在 React js 中显示上传图像的预览时出现图像为空的错误

c - 当符号链接(symbolic link)后跟 `..` 时 [file normalize $path] 和 realpath($path) 之间的行为差​​异

android - 避免在 TextView 中的特定位置换行