Understanding Variadic Functions, Defer, Panic, and Recover in Go
Variadic Functions
A variadic function is the one that can be called with varying number of parameters.
fmt.Println
is a very good example of variadic function.To declare a variadic function, the type of final parameter is preceded by an ellipsis “…” which means that function may be called with any number of parameters.
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
result := sum(1, 2, 3, 4, 5) // function called with 5 args
result1 := sum() // function called with 0 args
fmt.Println("Sum:", result)
fmt.Println("Sum:", result1)
}
// Output:
Sum: 15
Sum: 0
The sum function returns the sum of zero or more integer arguments. Within the parameter list, the type of numbers is an []int slice.
Defer
A defer statement defers the function execution until the surrounding function returns.
package main
import "fmt"
func main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
// Output:
// Hello
// World
The deferred function calls are pushed onto a stack. When the surrounding function returns, the deferred calls are executed in LIFO manner
package main
import "fmt"
func main() {
fmt.Println("Counting...")
for i := 1; i < 4; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
// Output
Counting...
done
3
2
1
Deferred calls can be used in closing files or network connections, logging function call details.
Panic
The
panic
statement is used to terminate a program abruptly if something goes unexpectedly wrong.Could be used in cases like unrecoverable errors, logic inconsistency
package main
import "fmt"
func main() {
fmt.Println("Start")
panic("Panic!")
fmt.Println("Waiting to execute")
}
// Output:
// Start
// panic: Panic!
The program ends after the control executes the panic statement, that is why last print statement after panic is not executed.
package main
import "fmt"
func divide(a, b int) {
// this function returns the result of a/b
// if b is 0, program is terminated due to panic
if b == 0 {
panic("Cannot divide a number by zero")
} else {
result := a / b
fmt.Println("Result: ", result)
}
}
func main() {
divide(100, 10)
divide(7, 0)
divide(16, 4)
}
// Output
Result: 10
panic: Cannot divide a number by zero
Recover
Panic statement terminates the program, but sometimes it might be important for a program to complete it’s execution.
Recover statement is used to handle panic. It prevents the termination of the program and recovers from panic.
package main
import "fmt"
// Function to handle panic recovery
func recoverFromPanic() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}
// Function to perform division
func divide(a, b int) {
// Defer the recovery function
defer recoverFromPanic()
// Check if divisor is zero
if b == 0 {
panic("Cannot divide a number by zero")
}
// Perform the division
result := a / b
fmt.Println("Result:", result)
}
func main() {
// Normal division
divide(100, 10)
// Division by zero (will cause a panic)
divide(7, 0)
// Another normal division
divide(16, 4)
}
When a panic occurs in the
divide
function (in second function call), the deferred functionrecoverFromPanic
is executed. It captures the panic message and prints the recovery message. This prevents the panic from terminating the entire program, allowing subsequent code (if any) to execute.
That’s it for now. Until we meet next time, happy coding!!