Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Go Programming - From Beginner to Professional - Second Edition

You're reading from  Go Programming - From Beginner to Professional - Second Edition

Product type Book
Published in Mar 2024
Publisher Packt
ISBN-13 9781803243054
Pages 680 pages
Edition 2nd Edition
Languages
Author (1):
Samantha Coyle Samantha Coyle
Profile icon Samantha Coyle

Table of Contents (30) Chapters

Preface Part 1: Scripts
Chapter 1: Variables and Operators Chapter 2: Command and Control Chapter 3: Core Types Chapter 4: Complex Types Part 2: Components
Chapter 5: Functions – Reduce, Reuse, and Recycle Chapter 6: Don’t Panic! Handle Your Errors Chapter 7: Interfaces Chapter 8: Generic Algorithm Superpowers Part 3: Modules
Chapter 9: Using Go Modules to Define a Project Chapter 10: Packages Keep Projects Manageable Chapter 11: Bug-Busting Debugging Skills Chapter 12: About Time Part 4: Applications
Chapter 13: Programming from the Command Line Chapter 14: File and Systems Chapter 15: SQL and Databases Part 5: Building For The Web
Chapter 16: Web Servers Chapter 17: Using the Go HTTP Client Part 6: Professional
Chapter 18: Concurrent Work Chapter 19: Testing Chapter 20: Using Go Tools Chapter 21: Go in the Cloud Index Other Books You May Enjoy

Functions – Reduce, Reuse, and Recycle

Overview

This chapter will describe the various ways in which you can reduce, reuse, and recycle code. It will include a large overview of functions so that you can include parts of a function, such as defining the function, function identifiers, parameter lists, return types, and the function body. We will also look at best practices when designing code so that you can make it reusable and flexible and make your functional logic small and purposeful.

By the end of this chapter, you will be able to see how easy Go makes it to reduce, reuse, and recycle code. This will include how to describe a function and the different parts that make up a function and evaluate the scope of variables with functions. You will know how to create and call a function, as well as how to utilize variadic and anonymous functions and create closures for various constructs. You will also know how to use functions as parameters and return values and how to...

Technical requirements

For this chapter, you will need to install the Go programming language. This chapter’s code can be found in this book’s GitHub repository: https://github.com/PacktPublishing/Go-Programming-From-Beginner-to-Professional-Second-Edition-/tree/main/Chapter05.

Introduction

The ability to write code in a way that is easy to maintain and iterate on is a vital skill for an engineer. This means crafting it so that it may be reused, easily expanded upon, and understood by others. Go makes it easy to keep code clean and readable, and separate logical chunks together. The first major way of writing code that is easy to reduce, reuse, and recycle is through the use of functions.

Functions are a core part of many languages and Go is no exception. A function is a section of code that has been declared to perform a task. Go functions can have zero or more inputs and outputs. One feature that sets Go apart from other programming languages is the multiple return values; most programming languages are limited to one return value. This leads into Go’s flexibility and the ability for developers to continuously write adaptable code.

In the following section, we will see some features of Go functions that differ from other languages, such as...

Functions

Functions are a critical part of Go and we should understand their place. Let’s examine some of the reasons for using functions:

  • Breaking up a complex task: Functions are used to perform a task, but if that task is complicated, it should be broken down into smaller tasks. Functions can be used for small tasks to solve a bigger problem. Smaller tasks are more manageable, and using a function to solve specific tasks will make the entire code base easier to maintain.
  • Reducing code: A good indication that you should use a function is when you see similar code repeating throughout your program. When you have duplicate code, it increases the difficulty of maintenance. If you have one change to make, you will have multiple instances where your code needs to change.
  • Reusability: Once you have defined your function, you can use it repeatedly. It can also be used by other programmers. This sharing of functions will reduce lines of code and save time by allowing...

The checkNumbers function

Now that we have looked at the different parts of the function, let’s see how these parts work with various examples. Let’s start with a simple approach with a checkNumbers function. The checkNumbers function prints out various messages based on some math results of whether a number is even or odd. The rules perform one of the actions based on the number given:

  • If the number is even, print Even
  • If the number is odd, print Odd

The following is the code snippet to achieve this output:

func checkNumbers() {
    for i := 1; i <= 30; i++ {
        if i%2 == 0 {
            fmt.Println("Even")
        } else {
            fmt.Println("Odd")
        ...

Parameters

Parameters define what arguments can be passed to our function. Functions can have zero or more parameters. Even though Go allows us to define multiple parameters, we should take care not to have a huge parameter list; that would make the code harder to read. It may also be an indication that the function is doing more than one specific task. If that is the case, we should refactor the function. Take, for example, the following code snippet:

func calculateSalary(lastName string, firstName string, age int, state string, country string, hoursWorked int, hourlyRate, isEmployee bool) {
// code
}

The preceding code is an example of a function whose parameter list is bloated. The parameter list should pertain only to the single responsibility of the function. We should only define the parameters that are needed to solve the specific problem that the function is built for.

Parameters are the input types that our function will use to perform its task. Function parameters...

Naked returns

Note

Functions that have return values must have a return statement as the last statement in the function. If you omit the return statement, the Go compiler will give you an error stating “missing return at the end of the function.”

Typically, when a function returns two types, the second type is an error. We have not gone over errors yet, so we won’t be demonstrating them in these examples. It is good to know that, in Go, it is idiomatic for the second return type to be of the error type.

Go also allows you to ignore a variable being returned. For example, say we are not interested in the int value that is being returned from our checkNumbers function. In Go, we can use what is called a blank identifier, which allows us to ignore values in an assignment:

_, err := file.Read(bytes)

For example, when reading a file, we might not be concerned about the number of bytes read. So, in that case, we can ignore the value being returned by using...

Closures

So far, we have introduced anonymous function syntax using some basic examples. Now that we have a fundamental understanding of how anonymous functions work, we will look at how we can use this powerful concept.

Closures are a form of anonymous functions. Regular functions cannot reference variables outside of themselves; however, an anonymous function can reference variables external to their definition. A closure can use variables declared at the same level as the anonymous function’s declaration. These variables do not need to be passed as parameters. The anonymous function has access to these variables when it is called:

func main() {
  i := 0
  incrementor := func() int {
    i +=1
    return i
  }
  fmt.Println(incrementor())
  fmt.Println(incrementor())
  i +=10
  fmt.Println(incrementor())
}

Code synopsis:

  1. We initialize a variable in...

defer

The defer statement defers the execution of a function until the surrounding function returns. Let’s try to explain this a bit better. Inside a function, you have a defer statement in front of a function that you are calling. Essentially, that function will execute right before the function you are currently inside completes. Still confused? Perhaps an example will make this concept a little clearer:

package main
import "fmt"
func main() {
  defer done()
  fmt.Println("Main: Start")
  fmt.Println("Main: End")
}
func done() {
  fmt.Println("Now I am done")
}

The output for the defer example is as follows:

Main: Start
Main: End
Now I am done

Inside the main() function, we have a deferred function, defer done(). Notice that the done() function has no new or special syntax. It just does a simple print to the console.

Next, we have two print statements. The results are interesting....

Separating similar code

So far, we have covered a lot regarding functions since they are a vital aspect of what makes Go successful and flexible as a language. To continue with the idea of making flexible code for others to understand, iterate on, and work with, we will discuss how to expand this mentality.

In the world of software development, organizing code effectively is crucial for creating maintainable and scalable applications. In Go programming, one approach to achieving code organization is by separating related functions into different directories and utilizing multiple packages.

Thus far, we have been working with just one file to understand the fundamentals of Go. However, there is life beyond just a main.go file. We will briefly discuss ways Go developers keep in mind the reusability and cleanliness of their code, beyond the scope of functions. However, we will keep things at a high level at this point as we dive into the details of this when we cover Go modules...

Summary

In this chapter, we studied why and how functions are an essential part of the Go programming language. We also discussed various features of functions in Go that make Go stand apart from other programming languages. Go has features that allow us to solve a lot of real-world problems and do so in a small, iterable, and manageable way. Functions in Go serve many purposes, including enhancing the usage and readability of code.

Next, we learned how to create and call functions. We studied the various types of functions that are used in Go and discussed scenarios where each of the function types can be used. We also expounded on the concept of closures. Closures are essentially a type of anonymous function that can use variables declared at the same level as that at which the anonymous function was declared. Then, we discussed various parameters and return types and studied defer. We also discussed how to keep your code clean and separated such that similar logic can be packaged...

lock icon The rest of the chapter is locked
You have been reading a chapter from
Go Programming - From Beginner to Professional - Second Edition
Published in: Mar 2024 Publisher: Packt ISBN-13: 9781803243054
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}