Is there a difference between calling a function with a goroutine and wrapping a functions code in a goroutine?

Issue

I’m relatively new to Golang and I’m trying to wrap my head around the semantics of goroutines.
Is there a difference between:

func someFunc() {
    for {
        //some code handled by a persistent connection
    }
}

go someFunc()

and

func someFunc() {
    go func() {
        for {
            //some code handled by a persistent connection
        }
    }()
}

Solution

It’s a question of what you’re trying to communicate. Generally functions should represent behavior that isn’t tied to the mode of operation of that behavior. If someday your code becomes all asynchronous because of some business concern, it shouldn’t require touching any code inside of someFunc.

For that reason I would prefer the former to the latter, but ultimately both are spawning a goroutine and executing code on that thread. The advantage to the former is that running someFunc synchronously becomes possible.


There are other small differences as well. The first definition of someFunc is running until it finishes its behavior. Let’s imagine a long-running expensiveAction is taken during someFunc, such that the definition becomes:

func someFunc() {
    ok := expensiveAction()
    if !ok {
        panic("Something bad happened")
    }
}

and

func someFunc() {
    go func() {
        ok := expensiveAction()
        if !ok {
            panic("Something bad happened")
        }
    }()
}

The first definition of someFunc, when called, will run until expensiveAction has finished. The second definition will define the anonymous function, spin up the goroutine and schedule its execution, then immediately exit. This could make performance testing more difficult, or even create subtle timing bugs.

Answered By – Adam Smith

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.