Ninth Break: Functions in Go
Declaration, Named and optional Parameters, Multiple values types as Input parameters and Multiple and Named return Types

Hi everyone! this is Jimmy , and this is the Ninth article in my series “Breaking Things with Go.” In this series, I document my journey through Jon Bodner’s Second Edition: Learning Go – An Idiomatic Approach to Real-World Go Programming and explore how to use Go in the most practical way I can
in this series the resources are the book itself, go documentation, and any AI model to clarify some things
lets Jump into it

Long Time no see, Can’t Live without me ? Kidding chill out
in Today’s break we’ll be going through some topics of Functions in GO
Basic Declaration
I’m not gonna yap about what is functions and why it exist so I will assume that everyone knows what function is and we’ll go from there
let’s start with Basic Function declaration in Go
func func_name(Param_name param_type) return_type {//code}if you will return something you have to specify its type and no return needed if you won’t
if you need to exit function before its last line (if it doesn’t return anything) you can use return (known as naked-return in Go)
if the function returns data you can pass it around directly or you can assign it to variable first then pass it using that variable’s name
so function of simple division should look like
func div(num int, denom int) int{ // takes two integers, and returns int type
if denom == 0 {
return 0
}
return num / denom
}
BTW if there is two parameters of two types declared after each other you can write the type once func div(num, deno int) int {}
and you can just call it div(3, 5) or assign it to variable result:=div(3,5) or pass it around fmt.Println(div(3,5))
Named and Optional Parameters
Go doesn’t support named or optional parameters but we can simulate it using structs with the fields that matches the desired Parameters
struct must be declared on package level
package main
type MyFuncOpts struct {
FirstName string
LastName string
Age int
}
func MyFunc(opts MyFuncOpts) error {
// do something here
}
func main() {
MyFunc(MyFuncOpts{ // others are set to their zero value
LastName: "Patel",
Age: 50,
})
MyFunc(MyFuncOpts{
FirstName: "Joe",
LastName: "Smith",
})
}
if you found yourself using too much optional and name parameters refactor your functions
Variadic Input Parameters and Slices
variadic input means a function can accept a variable number of arguments of the same type
we indicate variadic input Parameters using three dots ... before the type and it has to be the last parameter
func addTo(base int, vals ...int) []int {
out := make([]int, 0, len(vals))
for _, v := range vals {
out = append(out, base+v)
}
return out
}
func main() {
fmt.Println(addTo(3)) // doesn't loop so it returns out slice empty []
fmt.Println(addTo(3, 2)) // 5
fmt.Println(addTo(3, 2, 4, 6, 8)) // 5 7 9 11
a := []int{2, 4, 6, 8}
fmt.Println(addTo(3, a...)) // 5 7 9 11
fmt.Println(addTo(3, []int{2, 4, 6, 8}...)) // 5 7 9 11
}
Multiple return values
go supports multiple return values unlike some programming languages
if you return multiple values you have to specify the return type for all values in a parentheses separated by a comma and you must return all of them
don't put parentheses around the returned values
returning an error in function → returns error if something goes wrong other wise it will return nil for the error value
func div(num, denom int) (int, int, error) {
if denom == 0 {
return 0, 0, errors.New("Can't divide by zero")
}
return num / denom, num % denom, nil // return nil if no error returned above
}
func main() {
result, remainder, err := div(5, 2) // assigned the returned values to variables
if err != nil { // checks if there is error returned
fmt.Println(err)
os.Exit(1)
}
fmt.Println(result, remainder)
}
Note that Multiple returns are Values meaning :
in python we can return multiple values but they are returned in a tuple but go returns actual multiple values that each of them need a variable to be assigned to
if function returns three values you need to assign them to 3 variables, otherwise you’ll get an error
if you wanna ignore value use
_and it will be ignoredyou can’t use
_and ignore all variables but you can drop the assignment in the first place and nothing happensdiv(4,2)without assignment but you’ll lose those values
Named return values
we can also name the returned values
they are pre-declared variables that we use within the function to hold the return values
written comma-separated list within parentheses (even if it's a single value)
initialized to their zero value on creation
if you don't need to name some of the variables use
_for its namethose names are local to the function only and doesn't enforce naming to the returned values assignment on calling
you can shadow them if you re-declared them inside the same function again (so if you don't wanna shadow them use = not
:=)
here is an example
func div(num, denom int) (result, remainder int, err error) { // same as parameters same types can be combined using comma and write the type once
if denom == 0 {
err = errors.New("Can't divide by zero")
return result, remainder, err
}
result, remainder = num/denom, num%denom // gave a value but not declaration
return result, remainder, err
}
func main() {
x, y, z := div(5, 2)
fmt.Println(x, y, z)
}
those variables are created to pre-declare the variables instead of declaring them inside the function but it is totally fine not to return them because you don't have to
- you can name variables and then return the values directly without assigning them to variable like this
func div(num, denom int) (result, remainder int, err error) {
err = nil
result, remainder = 10, 20
if denom == 0 {
return 0, 0, errors.New("Can't divide by zero")
}
return num/denom, num%denom, nil
}
func main() {
x, y, z := div(5, 2)
fmt.Println(x, y, z) // 2, 1, <nil>
}
don’t get me wrong → don’t have to return them doesn’t mean you can leave them unused (this is an error remember! )
Blank/Naked return
and it is a return statement without specified values, used in a function that has named parameters and it returns the value of the current named variables for example
func sum(a, b int) (result int){
result = a+b
return //returns the current value of result which is the summation
}
func summ(a, b int) (result int){
return // returns the current value of result which is its zero value of int 0
}
- don't use them cause they aren't good for readability and will leave developers confused
Takes
Go functions are explicit meaning that parameter types, return types, and error handling must always be clear and intentional
Variadic parameters are just slices inside the function, but
...is required at the call site to expand a sliceGo returns real multiple values (not tuples like python kingdom), and every returned value must be handled or explicitly ignored with
_Named and naked returns exist but should be used sparingly due to readability and maintainability concerns
Coming Next
the next break will dive more about function how are they treated, anonymous functions, closures and some cool stuff
so stick around for next break where we will break more stuff
break is over, time to get back to work
feel free to reach out to me / X
Tschüss Freunde






