Search code examples
gocoding-stylenaming-conventionscontrol-flowcontinue

What's the standard practice for naming labels in Go?


Go spec and Effective Go gives guidelines for naming packages, types, functions, and variables. There's also a blog post discussing about package names. But none of articles seem to talk about naming conventions of labels used with goto, break and continue.

I believe the best practice is to avoid labels altogether, but what's the standard convention for those control flow labels in Go?

Please note that this question is not asking for naming recommendations. I just thought it would be good to know what guidelines Google provide about it or how they actually use it.


Solution

  • According to the source code of the Go standard library and internal packages, they tend to name labels in the same manner variables are usually named.

    So it's okay for labels to have any combination of either upper or lower-case characters, as long as you don't use underscores for writing anything.

    See https://golang.org/doc/effective_go.html#mixed-caps

    MixedCaps

    Finally, the convention in Go is to use MixedCaps or mixedCaps rather than underscores to write multiword names.

    Some examples:

    https://golang.org/src/cmd/internal/obj/x86/pcrelative_test.go#L102

    continue LOOP
    

    https://golang.org/src/compress/lzw/reader.go#L198

    break loop
    

    https://golang.org/src/compress/flate/deflate.go#L402

    break Loop
    

    https://golang.org/src/debug/gosym/symtab.go#L429

    break countloop
    

    https://golang.org/src/encoding/csv/reader.go#L308

    break parseField
    

    https://golang.org/src/crypto/dsa/dsa.go#L128

    break GeneratePrimes
    

    https://golang.org/src/go/types/testdata/labels.src

    func f3() {
    L1:
    L2:
    L3:
        for {
            break L1 /* ERROR "invalid break label L1" */
            break L2 /* ERROR "invalid break label L2" */
            break L3
            continue L1 /* ERROR "invalid continue label L1" */
            continue L2 /* ERROR "invalid continue label L2" */
            continue L3
            goto L1
            goto L2
            goto L3
        }
    }
    

    All sample snippets from Go language spec write all labels in CamelCase. And the word Loop is often abbreviated to L in both the spec and the implementation.

    https://golang.org/ref/spec#Break_statements

    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
                }
            }
        }
    

    https://golang.org/ref/spec#Continue_statements

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

    https://golang.org/ref/spec#Goto_statements

    goto Error
    
        goto L  // BAD
        v := 3
    L:
    
    if n%2 == 1 {
        goto L1
    }
    for n > 0 {
        f()
        n--
    L1:
        f()
        n--
    }