---
date: 2020-08-26
id: 009236f9-033d-44ef-8fa4-73cb05c3b390
title: Golang Functions
---

# Arguments

## Basics

A function can take zero or more arguments. [Argument type comes after
the variable name](https://blog.golang.org/declaration-syntax).

``` go
package main

import "fmt"

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

func main() {
    fmt.Println(add(42, 13))
}
```

When two or more consecutive named function parameters share a type, you
can omit the type from all but the last

``` go
package main

import "fmt"

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

func main() {
    fmt.Println(add(42, 13))
}
```

## Variadic

Go also supports [variadic
functions](https://gobyexample.com/variadic-functions), ie functions
with any number of trailing arguments:

``` go
package main

import "fmt"

func sum(nums ...int) {
    fmt.Print(nums, " ")
    total := 0
    for _, num := range nums {
        total += num
    }
    fmt.Println(total)
}

func main() {

    sum(1, 2)
    sum(1, 2, 3)

    nums := []int{1, 2, 3, 4}
    sum(nums...)
}
```

# Returns

## Multiple results

A function can return any number of results

``` go
package main

import "fmt"

func swap(x, y string) (string, string) {
    return y, x
}

func main() {
    a, b := swap("hello", "world")
    fmt.Println(a, b)
}
```

## Named return values

Go's return values may be named. If so, they are treated as variables
defined at the top of the function. These names shoudl be used to
document the meaning of the return values. A \`return\` statement
without arguments returns the named return values. This is known as a
"naked" return. Naked return statements should be used only short
functions as they can harm readability in longer functions.

``` go
package main

import "fmt"

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

func main() {
    fmt.Println(split(17))
}
```

## Function values

Like in [JavaScript](20200613170905-javascript) functions can be passed
around

``` go
package main

import (
    "fmt"
    "math"
)

func compute(fn func(float64, float64) float64) float64 {
    return fn(3, 4)
}

func main() {
    hypot := func(x, y float64) float64 {
        return math.Sqrt(x*x + y*y)
    }
    fmt.Println(hypot(5, 12))

    fmt.Println(compute(hypot))
    fmt.Println(compute(math.Pow))
}
```

## Function closures

Like [JavaScript](20200613170905-javascript) function closures are
supported in Go as well

``` go
package main

import "fmt"

func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(
            pos(i),
            neg(-2*i),
        )
    }
}
```

# Implementing an Interface

Here is an example of a function implementing an
[interface](20200831171822-interfaces):

``` go
type BlindAlerter interface {
    ScheduleAlertAt(duration time.Duration, amount int)
}

// BlindAlerterFunc allows you to implement BlindAlerter with a function
type BlindAlerterFunc func(duration time.Duration, amount int)

// ScheduleAlertAt is BlindAlerterFunc implementation of BlindAlerter
func (a BlindAlerterFunc) ScheduleAlertAt(duration time.Duration, amount int) {
    a(duration, amount)
}
```
