Go Functions
A function in Go is a named, reusable block of code that performs a specific task. Functions can receive input through parameters, return one or more values, and be called from other parts of a program.
This tutorial explains how to declare and call Go functions, pass arguments, return values, use variadic parameters, create anonymous functions and closures, and distinguish functions from methods with receivers.
Go Function Declaration Syntax
The basic syntax for defining a function in Go is as follows:
func functionName(parameters) returnType {
// Function body
}
A Go function declaration can contain the following parts:
func: The keyword that begins a function declaration.- Function name: The identifier used to call the function.
- Parameters: Typed input variables placed inside parentheses. Parameters are optional.
- Return type: The type of the value returned to the caller. It is omitted when the function returns nothing.
- Function body: Statements enclosed in braces that run when the function is called.
Calling a Go Function
Declare a function at package scope and call it by writing its name followed by parentheses. Arguments supplied by the caller are assigned to the function’s parameters in the same order.
package main
import "fmt"
func displayMessage(message string) {
fmt.Println(message)
}
func main() {
displayMessage("Learning Go functions")
}
Output
Learning Go functions
Common Types of Functions in Go
Go functions may have parameters, return values, both, or neither. The following examples show the common declaration patterns.
1 Go Function Without Parameters or a Return Value
This function performs an action but does not receive input or return a result:
package main
import "fmt"
// Function without parameters and return value
func greet() {
fmt.Println("Hello, World!")
}
func main() {
greet() // Call the function
}
How the greet Function Works
- Declare the function:
greethas empty parentheses because it accepts no parameters. - Run its statements: The body prints a message with
fmt.Println. - Call the function:
greet()transfers execution to the function body.
greet Function Output

2 Go Function With Parameters
Parameters let a function receive values from its caller. Each parameter has a name and a type:
package main
import "fmt"
// Function with parameters
func add(a int, b int) {
fmt.Println("Sum:", a+b)
}
func main() {
add(10, 20) // Call the function with arguments
}
How Function Parameters Receive Arguments
- Declare parameters: The function
adddeclaresaandbas parameters of typeint. - Pass arguments: In
add(10, 20),10is assigned toaand20tob. - Use parameter values: The function adds the values and prints the result.
add Function Output

Shortened Parameter Declarations of the Same Type
When consecutive parameters have the same type, Go permits the type to be written once after the final parameter name.
func add(a, b int) {
// a and b are both int values
}
This declaration is equivalent to func add(a int, b int).
3 Go Function With a Return Value
A function can calculate a value and return it to the calling code:
package main
import "fmt"
// Function with return value
func multiply(a int, b int) int {
return a * b
}
func main() {
result := multiply(5, 4) // Call the function and store the result
fmt.Println("Product:", result)
}
How a Go Function Returns a Value
- Declare the result type: The
intafter the parameter list specifies thatmultiplyreturns an integer. - Return the result:
return a * bsends the calculated product back to the caller. - Store the returned value: The caller assigns the returned integer to
result.
multiply Function Output

4 Go Function With Multiple Return Values
Go functions can return multiple values in a single call. This is commonly used when a calculation produces related results or when a function returns both a value and an error.
package main
import "fmt"
// Function with multiple return values
func divide(a int, b int) (int, int) {
return a / b, a % b // Return quotient and remainder
}
func main() {
quotient, remainder := divide(10, 3) // Call the function and capture results
fmt.Println("Quotient:", quotient)
fmt.Println("Remainder:", remainder)
}
How Multiple Return Values Are Collected
- Declare result types:
(int, int)indicates that the function returns two integers. - Return values in order: The quotient is returned first and the remainder second.
- Assign both results: The caller receives the values in
quotientandremainderin the corresponding order.
divide Function Output

Ignoring an Unneeded Return Value
Use the blank identifier _ when a function returns a value that the caller does not need.
quotient, _ := divide(10, 3)
fmt.Println(quotient)
Go does not allow a declared local variable to remain unused, so the blank identifier explicitly discards the second result.
5 Variadic Function in Go
A variadic function accepts zero or more arguments for its final parameter. Place ... before the parameter type to declare it:
package main
import "fmt"
// Variadic function
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
func main() {
fmt.Println("Sum:", sum(1, 2, 3, 4, 5)) // Call with multiple arguments
}
How the Variadic Parameter Works
- Declare a variadic parameter:
nums ...intaccepts any number of integer arguments. - Receive a slice: Inside the function,
numsbehaves as a value of type[]int. - Process every argument: The
rangeloop visits each supplied integer and adds it tototal.
Variadic sum Function Output

Passing a Slice to a Variadic Function
To pass an existing slice as the variadic arguments, append ... to the slice expression.
values := []int{4, 8, 12}
result := sum(values...)
fmt.Println(result)
Output
24
A function can have other parameters before a variadic parameter, but the variadic parameter must be last.
Named Return Values in Go Functions
Go permits names to be assigned to return values in the function signature. These names act as variables within the function body.
package main
import "fmt"
func rectangle(size int) (width int, height int) {
width = size * 2
height = size
return
}
func main() {
w, h := rectangle(5)
fmt.Println("Width:", w)
fmt.Println("Height:", h)
}
How a Bare Return Uses Named Results
The final return statement does not list expressions because width and height are named result variables. This form is called a bare return.
Named results can document what each returned value represents, but explicit return expressions are often clearer in longer functions.
Output
Width: 10
Height: 5
Functions as Values and Function Types in Go
Functions are values in Go. A function can be assigned to a variable, passed to another function, or returned from a function. The variable’s function type must match the parameter and result types of the assigned function.
package main
import "fmt"
func subtract(a, b int) int {
return a - b
}
func main() {
operation := subtract
result := operation(10, 4)
fmt.Println(result)
}
In this example, operation has the function type func(int, int) int.
Passing a Function as an Argument
A higher-order function accepts another function as an argument or returns a function as its result.
package main
import "fmt"
func calculate(a, b int, operation func(int, int) int) int {
return operation(a, b)
}
func addValues(a, b int) int {
return a + b
}
func main() {
result := calculate(7, 3, addValues)
fmt.Println(result)
}
Output
10
Anonymous Functions and Closures in Go
An anonymous function is a function literal without a declared name. It can be assigned to a variable or invoked immediately.
package main
import "fmt"
func main() {
square := func(number int) int {
return number * number
}
fmt.Println(square(6))
}
Go Closure That Retains Enclosing Variables
A closure is a function value that refers to variables from its surrounding scope. The function retains access to those variables while the closure remains reachable.
package main
import "fmt"
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
next := counter()
fmt.Println(next())
fmt.Println(next())
fmt.Println(next())
}
Closure Output
1
2
3
Each call to next updates the same captured count variable. Calling counter() again would create a separate closure with its own count.
Recursive Functions in Go
A recursive function calls itself. It must include a condition that stops further calls; otherwise, recursion continues until the program exhausts the available stack.
package main
import "fmt"
func factorial(number int) int {
if number <= 1 {
return 1
}
return number * factorial(number-1)
}
func main() {
fmt.Println(factorial(5))
}
How the Recursive Factorial Function Stops
The condition number <= 1 is the base case. For factorial(5), the function evaluates 5 × 4 × 3 × 2 × 1 and returns 120.
Output
120
Go Functions Versus Methods With Receivers
A regular function is declared with a name immediately after func. A method includes a receiver parameter between func and the method name. The receiver associates the method with a defined type.
package main
import "fmt"
type Rectangle struct {
Width float64
Height float64
}
func area(width, height float64) float64 {
return width * height
}
func (rectangle Rectangle) Area() float64 {
return rectangle.Width * rectangle.Height
}
func main() {
shape := Rectangle{Width: 6, Height: 4}
fmt.Println(area(shape.Width, shape.Height))
fmt.Println(shape.Area())
}
Reading the Method Receiver Syntax
func area(...)declares a regular package-level function.func (rectangle Rectangle) Area()declares a method with a value receiver of typeRectangle.- The method is called with selector syntax:
shape.Area(). - A pointer receiver, such as
func (rectangle *Rectangle) Resize(), is commonly used when a method must modify the receiver or avoid copying a large value.
The receiver is not a special form of return value. It is the parameter that identifies the type to which the method belongs.
How Go Passes Function Arguments
Go passes arguments by value. A function receives a copy of each argument value. Assigning a new value to a parameter does not replace the caller’s original variable.
package main
import "fmt"
func changeValue(number int) {
number = 100
}
func main() {
value := 10
changeValue(value)
fmt.Println(value)
}
Output
10
Using a Pointer Parameter to Modify a Variable
Pass a pointer when a function needs to update a caller-owned variable.
package main
import "fmt"
func changeValue(number *int) {
*number = 100
}
func main() {
value := 10
changeValue(&value)
fmt.Println(value)
}
Output
100
The pointer itself is still passed by value, but it refers to the original variable, allowing the function to update the value stored at that address.
Function Naming and Export Rules in Go
- A function name must be a valid Go identifier and cannot be a keyword.
- Names are case-sensitive, so
calculateandCalculateare different identifiers. - A name beginning with an uppercase Unicode letter is exported from its package.
- A lowercase function name is accessible only from within the same package.
- Go code commonly uses mixedCaps or MixedCaps rather than underscores in function names.
For example, ParseFile may be called by another package when its containing package is imported, while parseFile remains unexported.
Common Go Function Mistakes
- Placing the return type before the function name: Go places result types after the parameter list.
- Using arguments with incompatible types: The supplied values must be assignable to the declared parameter types.
- Forgetting to use a returned value: Capture the result or explicitly discard it with
_when multiple values are returned. - Putting a variadic parameter before another parameter: A variadic parameter must be the final parameter.
- Expecting an ordinary value parameter to modify the caller’s variable: Use a pointer or return the modified value.
- Writing recursion without a reachable base case: Every recursive path must eventually stop.
- Confusing a method receiver with a parameter list: The receiver appears before the method name and associates the method with a type.
Frequently Asked Questions About Go Functions
What does func mean in Go?
func is the Go keyword used to declare a function, method, or function literal. A named function uses the form func name(...), while a method places a receiver between func and the method name.
Can a Go function return more than one value?
Yes. Place the result types in parentheses, such as (int, error), and return the corresponding values in the same order. Multiple returns are commonly used to return a result together with an error.
What is the difference between a Go function and a method?
A function is declared at package scope without a receiver. A method has a receiver associated with a defined type and is commonly called through selector syntax, such as value.Method().
Can a Go function be stored in a variable?
Yes. Functions are values in Go. A function can be assigned to a variable when its signature matches the variable’s function type. It can also be passed as an argument or returned from another function.
Does Go support optional function parameters?
Go does not provide optional parameters or default argument values in ordinary function declarations. Common alternatives include separate functions, configuration structs, or a variadic parameter when accepting zero or more values of one type is appropriate.
Go Functions Editorial QA Checklist
- Verify that each function signature places parameters before result types.
- Confirm that every returned expression is assignable to the declared result type.
- Check that multiple return values are assigned or discarded in the correct order.
- Confirm that every variadic parameter is last and that slice expansion uses
slice.... - Check that recursive examples contain a reachable base case.
- Verify that method examples place the receiver before the method name and use an appropriate value or pointer receiver.
- Run each complete example with
go runand compare its output with the tutorial.
Go Function Rules to Remember
- Functions and methods begin with the
funckeyword. - Parameters and results are statically typed.
- A function may return no value, one value, or multiple values.
- Consecutive parameters of the same type may share one type declaration.
- Variadic parameters receive their arguments as a slice and must appear last.
- Functions can be assigned, passed, and returned as values.
- Closures retain access to variables from their surrounding scope.
- Arguments are passed by value; use pointers when direct mutation is required.
- Function names beginning with an uppercase letter are exported from their package.
TutorialKart.com