Deeper in Functions
Variables of Type Function
Functions in Go are values. The function type is composed of the func keyword followed by the parameters and return values, creating the function signature. Functions with the same number and types of parameters and return values meet the function signature. The default zero value for a function variable is nil.
Using Func Type Variables
$ go run src/function/value_func.go
TEST1 A PARAM: CALLING funcSignature
RESULT: 10
TEST2 b PARAM: CALLING AGAIN funcSignature
RESULT: 200
package main
import "fmt"
func test1(a string) int {
fmt.Println("TEST1 A PARAM: ", a)
return 10
}
func test2(b string) int {
fmt.Println("TEST2 b PARAM: ", b)
return 200
}
func main() {
var funcSignature func(string) int
funcSignature = test1
result := funcSignature("CALLING funcSignature")
fmt.Println("RESULT: ", result)
funcSignature = test2
result = funcSignature("CALLING AGAIN funcSignature")
fmt.Println("RESULT: ", result)
}
Function Type Declarations
The type keyword can be used to define a function type, just like is used to create a struct. Any function that meets the defined function signature type can be considered as a variable of that type.
Creating a Function Type
Anonymous Functions
Go supports anonymous functions, which can be assigned to variables or passed as arguments to other functions. Inner functions are anonymous, they don't have a name.
You can call an anonymous function immediately after the creation. This is common in two situations: defer statements and creating goroutines.
Creating and Calling Two Anonymous Functions
package main
import "fmt"
func main() {
add := func(a, b int) int {
return a + b
}
result1 := add(2, 4)
fmt.Println("Result1: ", result1)
result1 = add(3, 4)
fmt.Println("Result1: ", result1)
result1 = add(4, 4)
fmt.Println("Result1: ", result1)
result2 := func(a, b int) int {
return a + b
}(10, 10)
fmt.Println("Result2: ", result2)
}
Closures
Closures are functions declared inside function. This is a computer science term that means that closures can access and modify variables declared in the outer function. They can capture and use variables from their surrounding scope.
Shadow Variable
Using := instead of = inside the closure creates a new variable inside the function scope.
Closures allow to limit of a function's scope. When a function is called from only one other function, an inner function can be used, reducing declarations at the package level. Repeated code logic within a function can be encapsulated into a closure.
Closures Example
$ go run src/function/closures.go
Inner Function -> closure1: 10
closure1 ENDING: 30
Inner Function -> closure2: 10
Inner Function SHADOW DATA -> closure2: 30
closure2 ENDING: 10
package main
import "fmt"
func closure1() {
data := 10
func() {
fmt.Println("Inner Function -> closure1: ", data)
data = 30
}()
fmt.Println("closure1 ENDING: ", data)
}
func closure2() {
data := 10
func() {
fmt.Println("Inner Function -> closure2: ", data)
data := 30
fmt.Println("Inner Function SHADOW DATA -> closure2: ", data)
}()
fmt.Println("closure2 ENDING: ", data)
}
func main() {
closure1()
fmt.Println()
closure2()
}