Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The go statement starts the execution of a function call as an independent concurrent thread of control, known as a goroutine, within the same address space. It delegates the scheduling, multiplexing, and execution of the function to the Go runtime rather than the underlying operating system.

Syntax

The syntax requires the go keyword followed by an expression that must syntactically be a function or method call. The call itself cannot be parenthesized.
go Expression
Invalid Syntax Examples:
go (myFunc())      // Syntax error: expression cannot be parenthesized
x := go doWork()   // Syntax error: cannot capture return values

Evaluation and Execution Mechanics

When the Go compiler and runtime encounter a go statement, the evaluation of the expression is split across two distinct execution contexts:
  1. Calling Goroutine (Current Context): The function value, method receiver (if applicable), and all arguments are evaluated in the original, calling goroutine. This guarantees that the state passed to the new goroutine is captured at the exact moment the go statement is executed.
  2. New Goroutine (Concurrent Context): The actual execution of the function body occurs in the newly allocated goroutine.
Because the execution is asynchronous, the calling goroutine does not block. It immediately proceeds to the next statement following the go statement.

Syntax Visualizations

The go statement can invoke named functions, anonymous functions (closures), and methods.
// 1. Invoking a named function
go computeHash(payload)

// 2. Invoking a method on a struct/interface
go server.Listen()

// 3. Invoking an anonymous function (closure)
go func(id int) {
    // execution body
}(currentID)

Technical Constraints and Behavior

  • Return Values: If the invoked function or method returns any values, those values are entirely discarded by the runtime upon completion.
  • Built-in Functions: The function call is subject to the same restrictions as standard expression statements. You cannot use certain built-in functions directly with the go keyword. Attempting to use built-ins that do not represent valid expression statements (e.g., go len(mySlice), go make(chan int), or go append(s, "x")) will result in compilation errors.
  • Memory Space: The new goroutine shares the same memory address space as the calling goroutine. Mutations to shared variables are visible across goroutines, necessitating explicit synchronization (like mutexes or channels) to prevent data races.
  • Lifecycle and Termination: A goroutine terminates when its function returns. However, if the primary goroutine (the one executing main()) terminates, the Go runtime immediately shuts down, abruptly terminating all other running goroutines regardless of their current execution state.
  • Closure Variable Capture: When using anonymous functions, variables captured from the surrounding lexical scope are captured by reference. As of Go 1.22, for loop variables are scoped per-iteration rather than per-loop. This means capturing a loop variable directly within a goroutine closure safely binds to that specific iteration’s instance of the variable, eliminating the classic loop mutation data race that previously required passing the variable as an explicit function argument.
// Safe as of Go 1.22: 'v' is scoped per-iteration.
// The closure safely captures the iteration-specific variable by reference.
for _, v := range items {
    go func() {
        print(v) 
    }() 
}
Master Go with Deep Grasping Methodology!Learn More