Functions in Go
- Functions are
first-class citizens
, meaning theycan be passed around like any other variable
.
Basic Function Definition
In Go, a function is defined using the func
keyword. It can take parameters and return values.
- if multiple parameters are same, just comma separate them and in the end mention datatype
Multiple return values
func swap(a, b int) (int, int) {
return b, a
}
func main(){
x, y := swap(1, 2)
fmt.Println(x, y) // Output: 2 1
}
err != nil
concept
This multi-return feature is heavily used by Gofers for error handling.
- First value is the success value, second value is the error value.
- If the function returns an error, the second value will be non-nil.
- If the function returns a value, the second value will be nil.
Named Return Values
func divide(a, b int) (result int, err error) {
if b == 0 {
err = fmt.Errorf("division by zero")
return
}
result = a / b
return
}
Variadic Functions
- A variadic function allows you to pass a variable number of arguments of a specific type.
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
func main() {
result := sum(1, 2, 3, 4, 5)
fmt.Println(result) // Output: 15
}
Defer, Panic and Recover
Defer
- executes a statement just before the completion of the function
- if multiple defer statements are present, they are executed in reverse order (stack - LIFO)
- used as cleanup code, e.g., closing a file, releasing a lock, etc.
// output: counting, 3, 2, 1
func defer_in_func() {
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
fmt.Println("counting")
}
Panic
- Panic is a built-in function that stops the ordinary flow of control and begins panicking.
- When the function F calls panic, execution of F stops, any deferred functions in F are executed normally, and then F returns to its caller.
- To the caller, F then behaves like a call to panic. The process continues up the stack until all functions in the current goroutine have returned, at which point the program crashes.
Panics can be initiated by invoking panic directly. They can also be caused by runtime errors, such as out-of-bounds array accesses
.
func main() {
fmt.Println("hello")
defer fmt.Println("deferred print")
panic("panicked")
fmt.Println("world")
}
Recover
- Recover is a built-in function that regains control of a panicking goroutine.
- Recover is only useful inside deferred functions.
- During normal execution, a call to recover will return nil and have no other effect.
- If the current goroutine is panicking, a call to recover will capture the value given to panic and resume normal execution.
package main
import "fmt"
func main() {
f()
fmt.Println("Returned normally from f.")
}
func f() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
fmt.Println("Calling g.")
g(0)
fmt.Println("Returned normally from g.")
}
func g(i int) {
if i > 3 {
fmt.Println("Panicking!")
panic(fmt.Sprintf("%v", i))
}
defer fmt.Println("Defer in g", i)
fmt.Println("Printing in g", i)
g(i + 1)
}
functions as arguments
- You can assign functions to variables, pass functions as arguments, and return them from other functions.
func multiply(a, b int) int {
return a * b
}
func applyOperation(a, b int, op func(int, int) int) int {
return op(a, b)
}
func main(){
result := applyOperation(5, 3, multiply)
fmt.Println(result) // Output: 15
}
closure
/python type decorator functions in go
We can use this feature as decorator function in go.
Closure in Go
A closure is a function value that references variables from outside its body.
- The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables.
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))
}
}
Anonymous function in Go
- a function that doesnβt have a name
package main
import "fmt"
func main() {
// Anonymous function (defined and called immediately)
func() {
fmt.Println("Welcome! to GeeksforGeeks")
}()
}
- passing arguments to anonymous function
package main
import "fmt"
func main() {
// Passing arguments in anonymous function
func(ele string) {
fmt.Println(ele)
}("GeeksforGeeks")
}
- Assigning anonymous function to a Variable
package main
import "fmt"
func main() {
// Assigning an anonymous function to a variable
value := func() {
fmt.Println("Welcome! to GeeksforGeeks")
}
value()
}
- passing anonymous function as function argument