Functions

suggest change

Basic function usage:

// addCheckOverflow adds two int16 numbers and additionally
// returns true if the result overflowed
func addCheckOverflow(a, b uint16) (uint16, bool) {
	res := a + b
	didOverflow := res < a || res < b
	return res, didOverflow
}

func main() {
	res, didOverflow := addCheckOverflow(1, 3)
	fmt.Printf("%5d + %5d = %5d, did overflow?: %v\n\n", 1, 3, res, didOverflow)
	res, didOverflow = addCheckOverflow(65520, 10000)
	fmt.Printf("%5d + %5d = %5d, did overflow?: %v\n", 65550, 10000, res, didOverflow)
}
    1 +     3 =     4, did overflow?: false

65550 + 10000 =  9984, did overflow?: true

Parameters

A function can optionally declare a set of parameters:

func SayHelloToMe(firstName, lastName string, age int) {
	fmt.Printf("Hello, %s %s!\n", firstName, lastName)
	fmt.Printf("You are %d\n", age)
}

func main() {
	SayHelloToMe("John", "Doe", 35)
}
Hello, John Doe!
You are 35

Type for firstName is omitted because it is identical to lastName.

Return values

A function can return one or more values to the caller:

func Add(a, b int) int {
	return a + b
}

func AddAndMultiply(a, b int) (int, int) {
	return a + b, a * b
}

func main() {
	sum, mult := AddAndMultiply(5, 8)
	fmt.Printf("5+8=%d, 5*8=%d\n", sum, mult)
	sum = Add(6, 12)
	fmt.Printf("6+12=%d\n", sum)
}
5+8=13, 5*8=40
6+12=18

Named return values

You can name returned values in which case they act as implicit local variable.

An empty return statement can then be used to return their current values. This is known as “naked” return.

func inverse(v float32) (reciprocal float32) {
	if v == 0 {
		return
	}
	reciprocal = 1 / v
	return
}

// function can return multiple values
func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return
}

func main() {
	fmt.Printf("inverse(5)=%.2f\n", inverse(5))
}
inverse(5)=0.20

Two important things must be noted:

Using named return values is considered a bad practice that hinders readability, especially in longer function. Explicit is better than implicit.

Variadic functions

A variadic function can be called with any number of trailing arguments. Those elements are stored in a slice.

func variadic(strs ...string) {
	// strs is a slice of string
	for i, str := range strs {
		fmt.Printf("%d: %s\n", i, str)
	}
	fmt.Print("\n")
}

func main() {
	variadic("Hello", "Goodbye")
	variadic("Str1", "Str2", "Str3")

	// you can also give a slice to a variadic function, with `...`:
	strs := []string{"a", "b"}
	variadic(strs...)
}
0: Hello
1: Goodbye

0: Str1
1: Str2
2: Str3

0: a
1: b

Function literals

A function literal is a function declared inline, without a name.

Simplest example of a function literal:

func main() {
	func() {
		fmt.Println("Hello!")
	}()
}
Hello!

Function literal with arguments:

func main() {
	func(str string) {
		fmt.Println(str)
	}("Hello!")
}
Hello!

Function literal using a variable (str) defined outside the function:

func main() {
	str := "Hello!"
	func() {
		fmt.Println(str)
	}()
}
Hello!

Functions using variables defined outside the function are called closures.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents