wiki/content/20200826151337-functions.md

195 lines
3.2 KiB
Markdown

---
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)
}
```