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