Difference between using "continue Label" versus using "break" to jump out of inner loop in Go

huangapple go评论82阅读模式
英文:

Difference between using "continue Label" versus using "break" to jump out of inner loop in Go

问题

为了跳出内部循环并继续外部循环,我们可以使用continue Label或使用break。以下是一个示例:

原始帖子中使用了continue Label模式:

guestList := []string{"bill", "jill", "joan"}
arrived := []string{"sally", "jill", "joan"}

CheckList:
for _, guest := range guestList {
    for _, person := range arrived {
        fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

        if person == guest {
            fmt.Printf("Let %s In\n", person)
            continue CheckList
        }
    }
}

通过使用break也可以实现相同的结果,如下所示:

guestList := []string{"bill", "jill", "joan"}
arrived := []string{"sally", "jill", "joan"}

for _, guest := range guestList {
    for _, person := range arrived {
        fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

        if person == guest {
            fmt.Printf("Let %s In\n", person)
            break
        }
    }
}

在Go语言中,哪种方式更符合惯用写法?

英文:

In order to jump out of inner loop, and continue with the outer loop, we could either use continue Label or use break.

Here's an example from http://www.goinggo.net/2013/11/label-breaks-in-go.html

The original post is using the continue Label pattern:

    guestList := []string{"bill", "jill", "joan"}
    arrived := []string{"sally", "jill", "joan"} 

CheckList:
    for _, guest := range guestList {
        for _, person := range arrived {
            fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

            if person == guest {
                fmt.Printf("Let %s In\n", person)
                continue CheckList
            }
        }
    }

The same result could be achieved through using break, as shown here:
http://play.golang.org/p/0YUjkdxxRE

guestList := []string{"bill", "jill", "joan"}
arrived := []string{"sally", "jill", "joan"}

for _, guest := range guestList {
	for _, person := range arrived {
		fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

		if person == guest {
			fmt.Printf("Let %s In\n", person)
			break
		}
	}
}

Which way is more idiomatic in Go?

答案1

得分: 5

我不知道是否有任何被广泛接受的标准来确定使用哪种方式。请注意,这两种方式并不等价。

看下面的例子:

for _,guest := range guestList {
    for _,person := range arrived {
        fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

        if person == guest {
            fmt.Printf("Let %s In\n", person)
            break
        }
    }
    fmt.Println("多余的行!")
}

OuterLoop:
for _,guest := range guestList {
    for _,person := range arrived {
        fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

        if person == guest {
            fmt.Printf("Let %s In\n", person)
            continue OuterLoop
        }
    }
    fmt.Println("多余的行!")
}

如果遇到breakcontinue,前者会打印"多余的行!",而后者不会。你使用哪种方式主要取决于你是否希望在内部循环终止后执行外部循环中的代码。如果没有这样的代码存在,那么主要取决于你是否认为将来会在那里添加代码。

请记住,你在代码中所表达的是语义。一个是说"我希望外部循环进行下一次迭代(如果没有则退出)"。另一个是说"我希望这个循环退出"。总的来说,我认为大多数人发现,尽可能影响和考虑最局部范围的代码通常是最清晰的。因此,除非必要,我会避免使用带标签的continue,但我认为无论哪种方式都不是一个很大的问题。

英文:

I don't know if there's any widely accepted standard for which to use. Note that these two are not equivalent, however.

Take:

for _,guest := range guestList {
    for _,person := range arrived {
        fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

        if person == guest {
            fmt.Printf("Let %s In\n", person)
            break
        }
    }
    fmt.Println("Superfluous line!")
}

vs

OuterLoop:
for _,guest := range guestList {
    for _,person := range arrived {
        fmt.Printf("Guest[%s] Person[%s]\n", guest, person)

        if person == guest {
            fmt.Printf("Let %s In\n", person)
            continue OuterLoop
        }
    }
    fmt.Println("Superfluous line!")
}

If the break or continue is hit, the former will print "Superfluous Line!", while the latter will not. Which you use largely depends on whether you want code in the outer loop to execute after your inner loop terminates. If no such code exists, then it largely depends on whether you think you'll ever add code there.

Keep in mind what you're saying semantically in the code. One is saying "I would like the outer loop to go to its next iteration (or exit if none exists)". The other is saying "I would like this loop to exit". Overall, I think most people find that code that affects and considers, as much as possible, the most local scope is generally the clearest. For this reason I'd avoid the labelled continue unless it's necessary, but I don't think it's a great holy affront either way.

huangapple
  • 本文由 发表于 2014年5月5日 06:41:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/23462390.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定