Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying Mastering Go
  • Table Of Contents Toc
Mastering Go

Mastering Go - Third Edition

By : Mihalis Tsoukalos
4.6 (16)
close
close
Mastering Go

Mastering Go

4.6 (16)
By: Mihalis Tsoukalos

Overview of this book

Mastering Go is the essential guide to putting Go to work on real production systems. This freshly updated third edition includes topics like creating RESTful servers and clients, understanding Go generics, and developing gRPC servers and clients. Mastering Go was written for programmers who want to explore the capabilities of Go in practice. As you work your way through the chapters, you’ll gain confidence and a deep understanding of advanced Go concepts, including concurrency and the operation of the Go Garbage Collector, using Go with Docker, writing powerful command-line utilities, working with JavaScript Object Notation (JSON) data, and interacting with databases. You’ll also improve your understanding of Go internals to optimize Go code and use data types and data structures in new and unexpected ways. This essential Go programming book will also take you through the nuances and idioms of Go with exercises and resources to fully embed your newly acquired knowledge. With the help of Mastering Go, you’ll become an expert Go programmer by building Go systems and implementing advanced Go techniques in your projects.
Table of Contents (17 chapters)
close
close
14
Other Books You May Enjoy
15
Index

Pointers

Go has support for pointers but not for pointer arithmetic, which is the cause of many bugs and errors in programming languages like C. A pointer is the memory address of a variable. You need to dereference a pointer in order to get its value—dereferencing is performed using the * character in front of the pointer variable. Additionally, you can get the memory address of a normal variable using an & in front of it.

The next diagram shows the difference between a pointer to an int and an int variable.

Graphical user interface

Description automatically generated

Figure 2.4: An int variable and a pointer to an int

If a pointer variable points to an existing regular variable, then any changes you make to the stored value using the pointer variable will modify the regular variable.

The format and the values of memory addresses might be different between different machines, different operating systems, and different architectures.

You might ask, what is the point of using pointers since there is no support for pointer arithmetic. The main benefit you get from pointers is that passing a variable to a function as a pointer (we can call that by reference) does not discard any changes you make to the value of that variable inside that function when the function returns. There exist times where you want that functionality because it simplifies your code, but the price you pay for that simplicity is being extra careful with what you do with a pointer variable. Remember that slices are passed to functions without the need to use a pointer—it is Go that passes the pointer to the underlying array of a slice and there is no way to change that behavior.

Apart from reasons of simplicity, there exist three more reasons for using pointers:

  • Pointers allow you to share data between functions. However, when sharing data between functions and goroutines, you should be extra careful with race condition issues.
  • Pointers are also very handy when you want to tell the difference between the zero value of a variable and a value that is not set (nil). This is particularly useful with structures because pointers (and therefore pointers to structures, which are fully covered in the next chapter), can have the nil value, which means that you can compare a pointer to a structure with the nil value, which is not allowed for normal structure variables.
  • Having support for pointers and, more specifically, pointers to structures allows Go to support data structures such as linked lists and binary trees, which are widely used in computer science. Therefore, you are allowed to define a structure field of a Node structure as Next *Node, which is a pointer to another Node structure. Without pointers, this would have been difficult to implement and may be too slow.

The following code illustrates how you can use pointers in Go—create a text file named pointers.go and type the presented code.

package main
import "fmt"
type aStructure struct {
    field1 complex128
    field2 int
}

This is a structure with two fields named field1 and field2.

func processPointer(x *float64) {
    *x = *x * *x
}

This is a function that gets a pointer to a float64 variable as input. As we are using a pointer, all changes to the function parameter inside the function are persistent. Additionally, there is no need to return something.

func returnPointer(x float64) *float64 {
    temp := 2 * x
    return &temp
}

This is a function that requires a float64 parameter as input and returns a pointer to a float64. In order to return the memory address of a regular variable, you need to use & (&temp).

func bothPointers(x *float64) *float64 {
    temp := 2 * *x
    return &temp
}

This is a function that requires a pointer to a float64 as input and returns a pointer to a float64 as output. The *x notation is used for getting the value stored in the memory address stored in x.

func main() {
    var f float64 = 12.123
    fmt.Println("Memory address of f:", &f)

To get the memory address of a regular variable named f, you should use the &f notation.

    // Pointer to f
    fP := &f
    fmt.Println("Memory address of f:", fP)
    fmt.Println("Value of f:", *fP)
    // The value of f changes
    processPointer(fP)
    fmt.Printf("Value of f: %.2f\n", f)

fP is now a pointer to the memory address of the f variable. Any changes to the value stored in the fP memory address have an effect on the f value as well. However, this is only true for as long as fP points to the memory address of the f variable.

    // The value of f does not change
    x := returnPointer(f)
    fmt.Printf("Value of x: %.2f\n", *x)

The value of f does not change because the function only uses its value.

    // The value of f does not change
    xx := bothPointers(fP)
    fmt.Printf("Value of xx: %.2f\n", *xx)

In this case, the value of f, as well as the value stored in the fP memory address, does not change because the bothPointers() function does not make any changes to the value stored in the fP memory address.

    // Check for empty structure
    var k *aStructure

The k variable is a pointer to an aStructure structure. As k points to nowhere, Go makes it point to nil, which is the zero value for pointers.

    // This is nil because currently k points to nowhere
    fmt.Println(k)
    // Therefore you are allowed to do this:
    if k == nil {
        k = new(aStructure)
    }

As k is nil, we are allowed to assign it to an empty aStructure value with new(aStructure) without losing any data. Now, k is no longer nil but both fields of aStructure have the zero values of their data types.

    fmt.Printf("%+v\n", k)
    if k != nil {
        fmt.Println("k is not nil!")
    }
}

Just make sure that k is not nil—you might consider that check redundant, but it does not hurt to double-check.

Running pointers.go generates the following kind of output:

Memory address of f: 0xc000014090
Memory address of f: 0xc000014090
Value of f: 12.123
Value of f: 146.97
Value of x: 293.93
Value of xx: 293.93
<nil>
&{field1:(0+0i) field2:0}
k is not nil!

We revisit pointers in the next chapter where we discuss structures. Next, we discuss generating random numbers and random strings.

CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
Mastering Go
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist download Download options font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon