|
|
|
// ### Functions
|
|
|
|
// a simple function
|
|
|
|
func functionName() {}
|
|
|
|
|
|
|
|
// function with parameters (again, types go after identifiers)
|
|
|
|
func functionName(param1 string, param2 int) {}
|
|
|
|
|
|
|
|
// multiple parameters of the same type
|
|
|
|
func functionName(param1, param2 int) {}
|
|
|
|
|
|
|
|
// return type declaration
|
|
|
|
func functionName() int {
|
|
|
|
return 42
|
|
|
|
}
|
|
|
|
|
|
|
|
// Can return multiple values at once
|
|
|
|
func returnMulti() (int, string) {
|
|
|
|
return 42, "foobar"
|
|
|
|
}
|
|
|
|
var x, str = returnMulti()
|
|
|
|
|
|
|
|
// Return multiple named results simply by return
|
|
|
|
func returnMulti2() (n int, s string) {
|
|
|
|
n = 42
|
|
|
|
s = "foobar"
|
|
|
|
// n and s will be returned
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var x, str = returnMulti2()
|
|
|
|
|
|
|
|
// ### Functions As Values And Closures
|
|
|
|
func main() {
|
|
|
|
// assign a function to a name
|
|
|
|
add := func(a, b int) int {
|
|
|
|
return a + b
|
|
|
|
}
|
|
|
|
// use the name to call the function
|
|
|
|
fmt.Println(add(3, 4))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Closures, lexically scoped: Functions can access values that were
|
|
|
|
// in scope when defining the function
|
|
|
|
func scope() func() int{
|
|
|
|
outer_var := 2
|
|
|
|
foo := func() int { return outer_var}
|
|
|
|
return foo
|
|
|
|
}
|
|
|
|
|
|
|
|
func another_scope() func() int{
|
|
|
|
// won't compile because outer_var and foo not defined in this scope
|
|
|
|
outer_var = 444
|
|
|
|
return foo
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Closures: don't mutate outer vars, instead redefine them!
|
|
|
|
func outer() (func() int, int) {
|
|
|
|
outer_var := 2
|
|
|
|
inner := func() int {
|
|
|
|
outer_var += 99 // attempt to mutate outer_var from outer scope
|
|
|
|
return outer_var // => 101 (but outer_var is a newly redefined
|
|
|
|
// variable visible only inside inner)
|
|
|
|
}
|
|
|
|
return inner, outer_var // => 101, 2 (outer_var is still 2, not mutated by foo!)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ### Variadic Functions
|
|
|
|
func main() {
|
|
|
|
fmt.Println(adder(1, 2, 3)) // 6
|
|
|
|
fmt.Println(adder(9, 9)) // 18
|
|
|
|
|
|
|
|
nums := []int{10, 20, 30}
|
|
|
|
fmt.Println(adder(nums...)) // 60
|
|
|
|
}
|
|
|
|
// By using ... before the type name of the last parameter you can indicate that it takes zero or more of those parameters.
|
|
|
|
// The function is invoked like any other function except we can pass as many arguments as we want.
|
|
|
|
func adder(args ...int) int {
|
|
|
|
total := 0
|
|
|
|
for _, v := range args { // Iterates over the arguments whatever the number.
|
|
|
|
total += v
|
|
|
|
}
|
|
|
|
return total
|
|
|
|
}
|
|
|
|
|