mdawar.dev

A blog about programming, Web development, Open Source, Linux and DevOps.

Go - Functions

(Updated: )

Functions are declared using the func keyword, followed by the function’s name, the input parameters and the return values.

go
// A function can take 0 or more arguments.
// The `main` function is an example of a function
// that takes no arguments and returns no values.
func main() {
  // ...
}

// This function takes 2 `int` arguments and returns an `int` value.
func add(x int, y int) int {
  return x + y
}

// When 2 or more consecutive parameters have the same type
// the type can be omitted from all but the last.
func add(x, y int) int {
  return x + y
}

Returning Multiple Values

go
// A function can return multiple values.
func swap(x, y string) (string, string) {
  return y, x
}

Naming Result Parameters

The result parameters can be given names and used as regular variables:

  • They are initialized to their zero value when the function begins
  • Named return values can be used to document the meaning of these values
go
func UserInfo() (name string, lastname string) {
  // Assign values to the result parameter variables.
  // They are treated as variables defined at the top of the function.
  name = "John"
  lastname = "Doe"

  // A return statement without arguments will return the current values
  // of the result parameters (Not recommended).
  return

  // It's recommended to explicitly return the values for clarity.
  return name, lastname
}

Anonymous Functions

Functions without a name are called anonymous functions:

go
// Anonymous function assigned to a variable.
add := func(x, y int) int {
  return x + y
}

// The variable's type will be `func(int, int) int`.
add(2, 3)

Functions Are Values

go
// Functions can be assigned to variables.
f := func(x, y float64) float64 {
  return math.Sqrt(x*x + y*y)
}

// They can be passed as arguments to other functions.
func compute(fn func(float64, float64) float64) float64 {
  return fn(3, 4)
}

// Function passed as an argument.
compute(f)

// They can be returned from other functions.
func makeGreeter() func() {
  return func() {
    fmt.Println("Hello, world")
  }
}

// Assign the returned function to a variable.
greeter := makeGreeter()
// Call the function.
greeter()

Variadic Functions

A variadic function can accept an arbitrary number of arguments.

  • The final parameter in a variadic function must have a type prefixed with ..., it may be invoked with zero or more arguments for that parameter

  • The variadic parameter can be accessed as a slice with the function

go
// Function that accepts any number of `int` arguments.
func sum(numbers ...int) int {
  total := 0

  // The variadic parameter is a slice of integers `[]int`.
  for _, n := range numbers {
    total += n
  }

  return total
}

sum(1, 2, 3, 4, 5, 6)

// To pass a slice to a variadic function.
var nums = []int{1, 2, 3, 4, 5, 6}
// Use the ... syntax to pass the slice elements as separate arguments.
sum(nums...)

Function Types

Function types are used to define the signature of a function which includes the input parameters and return values.

go
// Function type that takes 2 `int` arguments and returns an `int`.
type AdderFunc func(x, y int) int

// A function type can be defined without named parameters or results
// each type stands for one item, this definition is equivalent to the above.
type AdderFunc func(int, int) int

// These 2 definitions are also equivalent.
type ExampleFunc func(x, y int) (result int, err error)
type ExampleFunc func(int, int) (int, error)

A function type can be used to define variables or function parameters that accept functions with the same signature.

go
func add(x, y int) int {
  return x + y
}

func sub(x, y int) int {
  return x - y
}

type CalcFunc func(int, int) int

// Define a variable of a function type.
// The value of an uninitialized variable of function type is `nil`.
var op CalcFunc // nil

// Any function with the same signature can be assigned to the variable.
op = add
op(1, 2) // 3

op = sub
op(5, 1) // 4

// Function types can be used for function parameters.
func Calculate(f CalcFunc, x, y int) int {
  return f(x, y)
}

Calculate(add, 1, 2) // 3
Calculate(sub, 5, 1) // 4