是否可以通过 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/