Go Basic: Understanding For, If Else, Switch, Functions, Range, Closures, Recursion in Go

Understanding control flow constructs in Go, Learning about functions and their applications, including closures and recursion

full lessons here👇:
https://programmerscareer.com/golang-basic-skill/

Generated by AI, there may be errors, for reference only

Topic: For, If Else, Switch

Control flow is a crucial aspect of all programming languages. It determines the order in which your code gets executed. In Golang, these are primarily if-elsefor, and switch.

For loop:

The for loop is the only looping construct present in Go. Here’s what a basic for loop looks like:

1
2
3
for i := 0; i < 10; i++ {  
fmt.Println(i)
}

This for loop prints the numbers from 0 to 9.

If-Else construct:

The if statement allows your program to conditionally execute code. You can combine multiple if statements with else if or else.

1
2
3
4
5
6
num := 10  
if num%2 == 0 {
fmt.Println(num, "is even")
} else {
fmt.Println(num, "is odd")
}

This if-else construct prints out whether a number is even or odd.

Switch Case construct:

switch statement is a shorter way to write a sequence of if - elsestatements. It runs the first case whose value is equal to the condition expression. Here’s an example:

1
2
3
4
5
6
7
8
9
fruit := "Apple"  
switch fruit {
case "Apple":
fmt.Println("This is an Apple")
case "Banana":
fmt.Println("This is a Banana")
default:
fmt.Println("This is neither an Apple nor a Banana")
}

This switch case construct prints out a statement based on the value of the fruit variable.

Topic: Functions

Now let’s dive into functions in Go!

Function Declaration:

Functions in Go are defined with the func keyword. The following is the general syntax for declaring a function:

1
2
3
func functionName(parameterName parameterType) returnType {  
// function body
}

For example, here’s a simple function that takes in two integers and returns their sum:

1
2
3
func addNumbers(num1 int, num2 int) int {  
return num1 + num2
}

Function Arguments:

Our addNumbers function takes two arguments, num1 and num2, that are both of type int. In Go, function arguments are provided in parentheses following the function name.

Return Types:

Our addNumbers function also returns a value of type int. The return type of a function is specified after the function parameters and before the function body. The return statement is used inside the function body to specify the result to be returned.

Topic: Using range in Go

range in Go is a keyword used in for loop to iterate over items of an array, slice, string or map.

Range in Arrays:

Here’s how you can use range with an array:

1
2
3
4
numbers := [6]int{10, 20, 30, 40, 50, 60}  
for i, num := range numbers {
fmt.Printf("The element at index %d is %d\n", i, num)
}

In this example, range returns two values: the index and the value at that index.

Range in Slices:

range works similarly for slices. If you had a slice instead of an array in the above example, the code would still work the same.

Range in Maps:

When used with maps, range returns the key and the value. Here’s an example:

1
2
3
4
5
6
m := make(map[string]int)  
m["key1"] = 10
m["key2"] = 20
for k, v := range m {
fmt.Printf("The value at key %s is %d\n", k, v)
}

range provides a simple and intuitive way to iterate over arrays, slices, and maps in Go.

Topic: Closures in Go

Closures are a special case of anonymous functions. Anonymous functions can form closures by capturing variables from the surrounding scope.

Defining Closures:

In Go, closures are defined right at the place where you need them, and optionally, they can be assigned to a variable or immediately invoked. Here is a simple example:

1
2
3
4
5
6
7
func main() {  
sum := func(a, b int) int {
return a + b
}
result := sum(3, 4)
fmt.Println(result) // Prints: 7
}

In this example, we define an anonymous function that takes two integers and returns their sum. We immediately assign this function to the sumvariable, making sum a-function-which-is a closure.

Understanding Closures:

Closures have access to variables from their surrounding scope. Here is a simple closure that keeps state:

1
2
3
4
5
6
7
8
9
10
11
12
13
func counter() func() int {  
var count int
return func() int {
count++
return count
}
}
func main() {
count := counter()
fmt.Println(count()) // Prints: 1
fmt.Println(count()) // Prints: 2
fmt.Println(count()) // Prints: 3
}

In this example, the counter function returns another function, which forms a closure over the count variable. Each time this returned function is called, it increments count and returns its value. This count variable persists across multiple calls to the count() function but is not accessible outside of it.

Topic: More on Closures in Go

Let’s dive deeper into the concept of closures in Go. It’s important to note that Go supports closures, which means that a function can have an ‘enclosed’ environment holding its own variables.

Consider following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main  

import "fmt"

func intSeq() func() int {
i := 0
return func() int {
i++
return i
}
}

func main() {
nextInt := intSeq()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
newInts := intSeq()
fmt.Println(newInts())
}

In this example, we call intSeq(), assigning the result (a function) to nextInt. This nextInt function value captures its own i value, which will be updated each time we call nextInt.

To confirm that the state is unique to that particular function, create and test a new one.

The output after running this program will be

1
2
3
4
1  
2
3
1

This characteristic of function values lets us use them in more interesting ways, such as the line nextInt := intSeq(). Depending on what you’re doing, using closures with encapsulated data can give your programs good structure.

Topic: Recursion in Go

Recursion is the process in which a function calls itself directly or indirectly. The corresponding function is called as a recursive function.

Understanding Recursion:

Let’s take an example of a simple recursive function in Go:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main  

import "fmt"

func recurse(count int) {
if count <= 0 {
fmt.Println("All done!")
return
}
fmt.Println(count)
recurse(count - 1)
}

func main() {
recurse(5)
}

In this function, the recurse function prints then calls itself with a decrementing counter until the counter becomes 0. Each nested call has its own count variable, and they do not interfere with each other.

Factorial Recursive Function:

The factorial function is a classic example of recursion. In mathematics, the factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n.

Here is a factorial implementation using recursion in Go:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main  

import "fmt"

func factorial(n int) int {
if n == 0 {
return 1
}
return n * factorial(n-1)
}

func main() {
fmt.Println(factorial(5)) // Prints: 120
}

In this factorial function, it calls itself multiplying n by the factorial of n-1until it gets down to 0, at which point it stops calling itself and starts unwinding, returning the computed values.

Keep in mind, while recursion can solve problems in a clear and concise manner, excessive or careless use can lead to a stack overflow error due to excessive function calls. Always ensure your recursive functions have a well defined and reachable base case.

中文文章: https://programmerscareer.com/zh-cn/go-basic-03/
Author: Wesley Wei – Twitter Wesley Wei – Medium
Note: If you choose to repost or use this article, please cite the original source.

Go Basic: Understanding Methods, Interfaces, Struct Embedding, Generics: Covering OOP concepts in Go Go Basic: Understanding Strings, Arrays, Slices, Maps, Structs and Pointers in Go

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×