我有一个外循环和一个内循环,每个循环都在一个范围内迭代。我想在内部循环中满足条件时退出外部循环。
我有一个解决方案,它使用两个'break',一个在内部循环内部,一个在外部循环内部,就在内部循环外部。 Here it is(一个非常简单的示例):
package main
import (
"fmt"
)
func main() {
word := ""
for _, i := range("ABCDE") {
for _,j := range("ABCDE") {
word = string(i) + string(j)
fmt.Println(word)
if word == "DC" {
break
}
}
if word == "DC" {
break
}
}
// More logic here that needs to be executed
}
此解决方案没有问题,但是对我来说,它看起来很修补而且很丑陋。有更好的方法吗?
在先前的解决方案中,我可以尝试在外循环之外设置另一个条件循环,并使用标签like so并继续使用。但是正如您所看到的,这种方法没有比带有中断解决方案的方法更优雅。
package main
import (
"fmt"
)
func main() {
word := ""
Exit:
for word != "DC" {
for _, i := range "ABCDE" {
for _, j := range "ABCDE" {
word = string(i) + string(j)
fmt.Println(word)
if word == "DC" {
continue Exit
}
}
}
}
// More logic here that needs to be executed
}
我在这里看到了与其他语言(C,C#,Python等)有关的类似问题。但是我真正感兴趣的是golang构造(例如“ for select”)是否有任何技巧。
答案 0 :(得分:6)
使用功能
package main
import (
"fmt"
)
func getWord() string {
word := ""
for word != "DC" {
for _, i := range "ABCDE" {
for _, j := range "ABCDE" {
word = string(i) + string(j)
fmt.Println(word)
if word == "DC" {
return word
}
}
}
}
}
func main(){
word := getWord()
}
编辑:感谢@peterSO,他指出了细节上的一些错误并提供了这个游乐场https://play.golang.org/p/udcJptBW9pQ
答案 1 :(得分:5)
最直接的方法似乎是:
func main() {
word := ""
isDone := false
for _, i := range("ABCDE") {
for _,j := range("ABCDE") {
word = string(i) + string(j)
fmt.Println(word)
isDone = word == "DC"
if isDone {
break
}
}
if isDone {
break
}
}
// other stuff
}
使用生成器的替代方法
不过,您也可以使用生成器来创建单词序列,如下所示:
func makegen () chan string {
c:= make(chan string)
go func () {
for _, i := range ("ABCDE") {
for _, j := range ("ABCDE") {
c <- string(i) + string(j)
}
}
close (c)
}()
return c
}
func main() {
word := ""
for word = range makegen() {
fmt.Println (word)
if word == "DC" {
break
}
}
// other code
}
答案 2 :(得分:5)
那去怎么样?
package main
import (
"fmt"
)
func main() {
word := ""
for _, i := range "ABCDE" {
for _, j := range "ABCDE" {
word = string(i) + string(j)
fmt.Println(word)
if word == "DC" {
goto Exit
}
}
}
Exit: // More logic here that needs to be executed
}
答案 3 :(得分:2)
使用break {label}
可以根据需要嵌套任何循环。只需将标签放在要打破的for
循环之前 。这与执行goto {label}
的代码非常相似,但我认为这有点优雅,但我认为是见仁见智。
package main
func main() {
out:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if i + j == 20 {
break out
}
}
}
}
更多详细信息:https://www.ardanlabs.com/blog/2013/11/label-breaks-in-go.html
答案 4 :(得分:1)
只需推迟您需要做的所有事情,然后照常返回即可。
package main
import (
"fmt"
)
func main() {
defer func() {
// More logic here that needs to be executed
}()
word := ""
for _, i := range "ABCDE" {
for _, j := range "ABCDE" {
word = string(i) + string(j)
fmt.Println(word)
if word == "DC" {
return
}
}
}
}
答案 5 :(得分:0)
将for循环包装在一个匿名的自调用函数中,然后在需要中断时返回
package main
func main() {
func() {
for i:= 0; i < 100; i++ {
for j:= 0; j < 100; j++ {
if (i == 5 && j == 5) {
return
}
}
}
}()
}