标签 - 中断vs继续vs goto

Anu*_*ope 5 loops goto go

我明白那个:

break - 停止进一步执行循环结构.

continue - 跳过循环体的其余部分并开始下一次迭代.

但是,当与标签结合使用时,这些陈述有何不同?

换句话说,这三个循环之间有什么区别:

Loop:
    for i := 0; i < 10; i++ {
        if i == 5 {
             break Loop
        }
        fmt.Println(i)
    }
Run Code Online (Sandbox Code Playgroud)

输出:

0 1 2 3 4


Loop:
    for i := 0; i < 10; i++ {
        if i == 5 {
             continue Loop
        }
        fmt.Println(i)
    }
Run Code Online (Sandbox Code Playgroud)

输出:

0 1 2 3 4 6 7 8 9


Loop:
    for i := 0; i < 10; i++ {
        if i == 5 {
             goto Loop
        }
        fmt.Println(i)
    }
Run Code Online (Sandbox Code Playgroud)

输出:

0 1 2 3 4 0 1 2 3 4 ...(无限)


Fra*_*yce 14

对于breakcontinue,附加标签允许您指定要引用的循环.例如,您可能想要break/ continue外部循环而不是嵌套的循环.

以下是Go文档中的示例:

RowLoop:
    for y, row := range rows {
        for x, data := range row {
            if data == endOfRow {
                continue RowLoop
            }
            row[x] = data + bias(x, y)
        }
    }
Run Code Online (Sandbox Code Playgroud)

这使您可以转到下一个"行",即使您当前正在迭代行中的列(数据).这是有效的,因为标签RowLoop是通过直接在它之前"标记"外环.

break可以使用相同的机制以相同的方式使用.以下是Go文档中的一个示例,用于何时break语句对于在switch语句内部时断开循环非常有用.没有标签,go会认为你突破了switch语句,而不是循环(这就是你想要的,这里).

OuterLoop:
    for i = 0; i < n; i++ {
        for j = 0; j < m; j++ {
            switch a[i][j] {
            case nil:
                state = Error
                break OuterLoop
            case item:
                state = Found
                break OuterLoop
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

因为goto,这更传统.它使程序在Label下执行命令.在您的示例中,这会导致无限循环,因为您反复进入循环的开头.

文档时间

用于break:

如果有标签,则必须是包含"for","switch"或"select"语句的标签,并且该标签的执行终止.

用于continue:

如果有一个标签,那么它必须是一个封闭的"for"语句,并且是执行进程的标签.

  • 这些标签的一个非常重要的用途是,如果您在循环中有一个switch语句,因为`break`将应用于该开关,而不是围绕它的循环。 (2认同)