mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-29 22:46:22 +00:00
195 lines
3.2 KiB
Markdown
195 lines
3.2 KiB
Markdown
|
---
|
||
|
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)
|
||
|
}
|
||
|
```
|