doubei2231
2018-08-24 01:07
浏览 68
已采纳

如何突破Go中的嵌套循环?

I have an outer and inner loop, each iterating over a range. I want to exit the outer loop when a condition is satisfied inside the inner loop.

I have a solution which works using two 'break's, one inside the inner loop and one inside the outerloop, just outside the inner loop (a very simplified case for demonstration):

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
}

Go Playground

There is no problem with this solution, but it just looks patched and ugly to me. Is there a better way to do this?

I can try and have another for conditional loop outside the outer loop in the previous solution and have a label and use continue with the label. But as you can see, this approach isn't any more elegant than the solution with break.

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
}

Go Playground

I have seen similar questions here pertaining to other languages (C, C#, Python etc). But what I am really interested to see is whether there is any trick with Go constructs such as 'for select'.

图片转代码服务由CSDN问答提供 功能建议

我有一个内部和外部循环,每个循环都在一个范围内迭代。 我想在内部循环中满足一个条件时退出外部循环。

我有一个解决方案,可以使用两个'break',一个在内部循环中,一个在外部循环中, 只是在内循环之外(一个非常简化的示例):

 包main 
 
import(
“ fmt” 
)
 
func main()  {
 
 word:=“” 
表示_,i:= range(“ ABCDE”){
 for _,j:= range(“ ABCDE”){
 word =字符串(i)+字符串 (j)
 fmt.Println(word)
如果单词==“ DC” {
中断
} 
} 
如果单词==“ DC” {
中断
} 
} \  n //这里需要执行更多的逻辑
} 
   
 
 

去游乐场

此解决方案没有问题,但对我来说它看起来很补丁而且很难看。 有没有更好的方法呢?

我可以尝试在先前的解决方案中,在外循环之外再有一个条件循环,并有一个标签,并继续使用该标签。 但是,正如您所看到的,这种方法没有比带有break的解决方案更好的方法。

 包main 
 
import(
“ fmt” 
)\  n 
func main(){
 
 word:=“” 
 
Exit:
 for word!=“ DC” {
 for _,i:= range“ ABCDE” {
 for _,j  :=范围“ ABCDE” {
 word =字符串(i)+字符串(j)
 fmt.Println(word)
,如果word ==“ DC” {
继续退出
} 
} 
  } 
} 
 //这里需要执行更多的逻辑
} 
   
 
 

去操场

我在这里看到了与其他语言(C,C#,Python等)有关的类似问题。 但是我真正感兴趣的是Go构造(例如“ for select”)是否有技巧。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • doutuo3899 2018-08-24 01:30
    已采纳

    use function

    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
                    }
                }
            }
        }
        return word
    }
    
    func main(){
        word := getWord()
    }
    

    Edit: thanks to @peterSO who points on some mistakes in the details and provides this playground https://play.golang.org/p/udcJptBW9pQ

    已采纳该答案
    打赏 评论
  • dsf12313 2018-08-24 01:35

    The most straightforward seems to be something like:

    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
    }
    

    An Alternative using a Generator

    However you could also do a generator to create the sequence of words as in:

    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
    }
    
    打赏 评论
  • dongpeng0127 2018-08-24 02:27

    How about goto?

    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
    }
    
    打赏 评论
  • douchaqi3369 2018-09-25 20:58

    Just defer anything you need to do and return as normal.

    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
                }
            }
        }
    }
    
    打赏 评论
  • dongqian8265 2019-02-09 02:48

    Use break {label} to break out of any loop as nested as you want. Just put the label before the for loop you want to break out of. This is fairly similar to the code that does a goto {label} but I think a tad more elegant, but matter of opinion I guess.

    package main
    
    func main() {
        out:
        for i := 0; i < 10; i++ {
            for j := 0; j < 10; j++ {
                if i + j == 20 {
                    break out
                }
            }
        }
    }
    

    More details: https://www.ardanlabs.com/blog/2013/11/label-breaks-in-go.html

    打赏 评论

相关推荐 更多相似问题