Declaring functions
A function is a named block of code that takes some inputs and produces an output. You have already been calling functions since Lesson 1 (fmt.Println, strings.ToUpper, len); this lesson covers how to write your own.
The basic shape:
func add(x int, y int) int {
return x + y
}
Read left to right:
funcis the keyword that starts every function declaration.addis the name. This follows the same rules as variable names, including the capitalisation convention (capitalised names are exported to other packages, lowercase names stay unexported inside the package).(x int, y int)is the parameter list: names paired with types, in that order.intafter the closing parenthesis is the return type. This function returns oneint.{ ... return x + y }is the body, with areturnstatement providing the value.
Types come after names
In C, Java, or TypeScript the same signature reads type-first:
int add(int x, int y)
Go reverses it: the name comes first, the type second.
func add(x int, y int) int
The rule holds in the places you have already seen: variable declarations (var x int), parameter lists, and return values. It is jarring at first and stops being jarring quickly.
It also makes grouped parameters read naturally, because consecutive names can share one type when the type comes last:
func add(x, y int) int {
return x + y
}
x and y are both int. This is the form you will see most often in real Go code.
Functions that return nothing
A function does not have to return anything. Drop the return type and you have a function that produces side effects only:
func greet(name string) {
fmt.Println("Hello,", name)
}
There is no void keyword in Go. Simply omitting the return type is how you say "no return".
Calling a function
You call a function by writing its name, followed by the arguments in parentheses. The arguments are evaluated and passed to the parameters in order:
func main() {
result := add(3, 4)
fmt.Println(result) // 7
greet("Kamran") // Hello, Kamran
}
If the function returns a value, you usually store it in a variable (or pass it directly into another call). If the function returns nothing, you call it as a statement on its own line.
Where functions live
All the functions in this lesson (and most of what you will write for a while) sit at the top level of the file, alongside main. This is the same "package scope" you met in the Variables lesson: a top-level func declaration is visible to every other function in the package, in the same way that a top-level var is:
package main
import "fmt"
var greeting = "Hello" // package scope
func say() {
fmt.Println(greeting) // 'greeting' is reachable here
}
func main() {
say() // 'say' is reachable here
}
Go does not let you declare a named function inside another function the way Python or JavaScript do:
func main() {
func inner() { // compile error: unexpected name inner, expected (
}
inner()
}
You can, however, bind an anonymous function to a local variable and call it through that variable, which gives you something very close to a local function. That pattern is covered in the "Functions as values" lesson later in this chapter.
Parameters and the variables you declare in the body live at function scope: they exist for one call and disappear when the function returns. Each call gets its own fresh copy of the parameters and locals; no call can see into another.
- Write a function called
multiplythat takes threeintparameters and returns their product. - Call
multiply(2, 3, 4)frommain. - Print the returned result so the program outputs
24on the last line.
7 Hello, Kamran 24