Golang: Function

By Xah Lee. Date: . Last updated: .

Function

A function is defined like this:

func fname(params_spec) return_type {body}

package main

import "fmt"

// ff is my function name
func ff(x int, y int) int {
    return x + y
}

func main() {
    fmt.Println(ff(3, 4)) // 7
}

Note: type specification comes after the variable name.

When two or more consecutive named function parameters share a type, you can omit the type except the last one.

package main

import "fmt"

func ff(x, y int) int {
    return x + y
}

func main() {
    fmt.Println(ff(3,4))
}

Multiple Return Values

A function can return more than 1 value.

func ff() (int, int, int) { return 3, 4, 5 }

To get these values, assign them to multiple variables, like this:

var a, b, c = ff()

package main

import "fmt"

// returns 2 values
func ff(x, y int) (int, int) {
    return x, y
}

func main() {
    var a, b = ff(3, 4)
    fmt.Println(a, b)
}

// prints 3 4

Function with multiple return values is frequently used in golang. The second value is usually a error state.

Named Return Values

The return values can be named.

func f(n int) (m int)

If named, they are treated as variables declared at the top of the function body.

package main

import "fmt"

func gg(n int) (m int) {
    m = n + 1
    return m
}

func main() {
    fmt.Println(gg(5))
}

// 6

Function is a Value

Function is a value. It can be assigned to a variable, passed as argument to a function, or returned by a function.

package main

import "fmt"

// assign a function to a variable
var hh = func() int {
    return 3
}

func main() {
    fmt.Println(hh()) // 3
}

Apply Function to Value Inline

Function can be applied by appending (arguments)

func(x int) int { return x + 1 }(3)

package main

import "fmt"

func main() {
    var x = func(x int) int { return x + 1 }(3)
    fmt.Println(x) // 4
}

Nested Function

To define a function inside a function, declare a variable and give it a function value. Like this:

var f = func(…) … {…}

or use the variable shortcut:

f := func(…) … {…}

package main

import "fmt"

func main() {
    // this is a function, inside the function main
    var ff = func(x int) int {
        return x + 1
    }
    fmt.Println(ff(3)) // 4
}

Function as Argument

package main

import "fmt"

func aa(n int) int {
    return n + 1
}

// ff takes a function arg
func ff(gg func(int) int) int {
    return gg(1)
}

func main() {

    fmt.Println(ff(aa)) // 2

}

Return a Function

When you define a function, e.g.

func fname(params_and_types) return_type {body}

You are also defining a type.

So when you define a function that returns a function, the return type spec is same as function declaration.

the return_type takes the form

func fname(params_and_types) return_type2

The whole thing looks like this:

func fname(params) func (params) return_type {body}

package main

import "fmt"

// ff returns a function gg
func ff(x int) func(int) int {
    var gg = func(y int) int { return y + x }
    return gg
}

func main() {
    fmt.Println(ff(1)(2)) // 3

}

Unspecified Number of Arguments

For unspecified number of argument (aka variadic function) , use this syntax, e.g.

func ff(args ...int)

package main

import "fmt"

// function with unspecified number of args
func ff(args ...int) string {

    // args is received as a slice
    fmt.Printf("%T\n", args) // []int

    // return the args in string representation
    return fmt.Sprintf("%#v", args)

}

func main() {

    fmt.Printf("%v\n", ff(3, 7))
    // prints
    // []int
    // []int{3, 7}

}

Slice to Function of Arguments

If you have a array (or slice) and you want to pass its elements to function as arguments, you can do:

ff(array ...)

[see Golang: Array]

[see Golang: Slice]

package main

import "fmt"

// add all args
func ff(args ...int) int {
    var total = 0
    for _, v := range args {
        total += v
    }
    return total
}

func main() {
    // slice
    var x = []int{3, 7, 10}

    // slice to args
    fmt.Printf("%v\n", ff(x...)) // 20
}

Closure

Golang's function is a closure.

Closure is a programing language feature. It means, the local variables of the function do not go away when the function exits, if the variable is still being used.

For example, when a function f defines a local variable x and a local function g, g uses x, and g is returned. Here, g still has access to x, even though f is no longer in context.

For programers, this means, you can create a function that maintains a state, without using global variable.

Closure is what you need to implement the class concept of Java.

package main

import "fmt"

// return a closure
func make_add_1() func(int) int {
    var i = 0

    var gg = func(x int) int {
        i += x
        return i
    }

    // the returned function gg, is called a “closure”
    return gg
}

func main() {
    var f = make_add_1()

    fmt.Println(f(1)) // 1
    fmt.Println(f(1)) // 2
    fmt.Println(f(1)) // 3

}

Reference

The Go Programming Language Specification - The Go Programming Language#Function_types

If you have a question, put $5 at patreon and message me.

Golang

  1. Compile, Run
  2. Source Encoding
  3. Package, Import
  4. Comment
  5. Print
  6. String
  7. Rune
  8. String as Chars
  9. Variable
  10. Zero Value
  11. Constant
  12. If Then Else
  13. Switch/Case
  14. Loop
  15. Basic Types
  16. Array
  17. Slice
  18. Map
  19. Struct
  20. Function
  21. regexp
  22. Read File
  23. Write to File
  24. Walk Dir
  25. Check File Exist
  26. System Call
  27. Get Script Path
  28. Pointer
  29. Defer
  30. Random Number

Examples

  1. match any regexp
  2. Validate Links
  3. Generate Sitemap

Reference

  1. Go Spec