Skip to content

Instantly share code, notes, and snippets.

@eduncan911
Created June 9, 2016 19:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eduncan911/a422423f5a42f1825f5ededf9610f1cd to your computer and use it in GitHub Desktop.
Save eduncan911/a422423f5a42f1825f5ededf9610f1cd to your computer and use it in GitHub Desktop.
Labels in GoLang
package main
import "fmt"
/*
Here's a use of labels in Go to continue a for loop
from within another for and within a switch case.
*/
func main() {
foo := []string{"a", "b", "c", "d", "e", "f", "g"}
bar := []string{"b", "d", "f"}
fooloop:
for _, v := range foo {
for _, v2 := range bar {
switch {
case v == v2:
continue fooloop
}
}
fmt.Println(v)
}
}
/*
output$ go run main.go
a
c
e
g
*/
@gyenabubakar
Copy link

Why would someone want to do this in the first place? Can you give a real-word usecase?

@eduncan911
Copy link
Author

eduncan911 commented May 6, 2021

Why would someone want to do this in the first place? Can you give a real-word usecase?

Real world? Most likely not, you would use goroutines instead as it's against best practices when you have more than 10 lines of code in any one function.

However, most low-level code is written in this matter (MOV,ATTR). I've seen converters that takes assembly and converts to C and other higher-level languages, filled with goto labels.

GOTO labels do have a place in complex logic functions where you would have a single-escape vector instead of dozens of return statements (with common logic).

Say for example:

func process() (o Object, err Error) {

    switch SomethingComplex {
        case 1:
            goto exit_silently
        case 2:
            goto exit_silently
        case 3:
            goto exit_silently
        case 4:
            goto exit_silently
        case 5:
            goto exit_silently

        case 97:
            goto exit_with_error
        case 98:
            goto exit_with_error
        case 99:
            goto exit_with_error
        default:
            goto exit_with_error
    }

exit_silently:
    o := build(1827.22, 6239, "james", safe)
    process(o)
    makeSafe(o)
    return o, nil
        
exit_with_error:
    o := build(99, 99, "", unsafe)
    processAndDump(o)
    makeUnSafe(o)
    err := ParseError(o)
    TraceOut(err)
    return o, err

}

I would not want to repeat all of those return logic statements, in each switch statement. The goto/label branches makes things DRY and cleans up the code. Personally, I don't write code this way in Golang. But, i have been known to handle quite complex logic in C++/C#/Java this way in the past.

GOTO/labels are not all that bad. It's the implementer/developer that may misuse them. There is a right way to use GOTO labels, and many many wrong ways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment