Use `go` before a function call to start that call as a goroutine. The caller continues immediately instead of waiting for the function to return. The function itself needs no special declaration; what changes is how it is called. section 5.2 section 1.2.3
Echo input while a timer runs
```go package main import ( "fmt" "io" "os" "time" ) func echo(in io.Reader, out io.Writer) { io.Copy(out, in) } func main() { fmt.Println("Type anything for up to 30 seconds") go echo(os.Stdin, os.Stdout) time.Sleep(30 * time.Second) fmt.Println("Timed out.") } ``` Run it with `go run echoback.go`, then type a line and press Enter. `echo` copies input in the background while `main` waits. The `go` call does not keep the program alive: when `main` finishes, the program ends even if `echo` is still working. The sleep demonstrates that lifetime constraint; for deadlines and timeouts in practice, consider `context.WithDeadline`. section 5.2
Starting a goroutine also changes how you coordinate and handle its work:
- Use channels to pass values between goroutines. An unbuffered channel blocks during the demonstrated send and receive, providing synchronization rather than relying on a timed sleep. section 1.2.3
- In a TCP listener, call `go handle(conn)` after accepting a connection so the listener can continue accepting others while each handler processes its request. section 4.3.5
- Place deferred `recover` logic inside the goroutine that performs work when that goroutine must handle a panic; the server handler example also closes its connection in the defer. section 4.3.5


