Book Image

Mastering Go – Third Edition - Third Edition

By : Mihalis Tsoukalos
5 (2)
Book Image

Mastering Go – Third Edition - Third Edition

5 (2)
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)
14
Other Books You May Enjoy
15
Index

Go constants

Go supports constants, which are variables that cannot change their values. Constants in Go are defined with the help of the const keyword. Generally speaking, constants can be either global or local variables.

However, you might need to rethink your approach if you find yourself defining too many constant variables with a local scope. The main benefit you get from using constants in your programs is the guarantee that their value will not change during program execution. Strictly speaking, the value of a constant variable is defined at compile time, not at runtime—this means that it is included in the binary executable. Behind the scenes, Go uses Boolean, string, or number as the type for storing constant values because this gives Go more flexibility when dealing with constants.

The next subsection discusses the constant generator iota, which is a handy way of creating sequences of constants.

The constant generator iota

The constant generator iota is used for declaring a sequence of related values that use incrementing numbers without the need to explicitly type each one of them.

The concepts related to the const keyword, including the constant generator iota, are illustrated in the constants.go file.

package main
import (
    "fmt"
)
type Digit int
type Power2 int
const PI = 3.1415926
const (
    C1 = "C1C1C1"
    C2 = "C2C2C2"
    C3 = "C3C3C3"
)

In this part, we declare two new types named Digit and Power2 that will be used in a while, and four new constants named PI, C1, C2, and C3.

A Go type is a way of defining a new named type that uses the same underlying type as an existing type. This is mainly used for differentiating between different types that might use the same kind of data. The type keyword can be used for defining structures and interfaces.

func main() {
    const s1 = 123
    var v1 float32 = s1 * 12
    fmt.Println(v1)
    fmt.Println(PI)
    const (
        Zero Digit = iota
        One
        Two
        Three
        Four
    )

The previous code defines a constant named s1. Here you also see the definition of a constant generator iota based on Digit, which is equivalent to the next declaration of four constants:

const (
    Zero = 0
    One = 1
    Two = 2
    Three = 3
    Four = 4
)

Although we are defining constants inside main(), constants can be normally found outside of main() or any other function or method.

The last part of constants.go is as follows.

    fmt.Println(One)
    fmt.Println(Two)
    const (
        p2_0 Power2 = 1 << iota
        _
        p2_2
        _
        p2_4
        _
        p2_6
    )
    fmt.Println("2^0:", p2_0)
    fmt.Println("2^2:", p2_2)
    fmt.Println("2^4:", p2_4)
    fmt.Println("2^6:", p2_6)
}

There is another constant generator iota here that is a little different than the previous one. Firstly, you can see the use of the underscore character in a const block with a constant generator iota, which allows you to skip unwanted values. Secondly, the value of iota always increments and can be used in expressions, which is what occurred in this case.

Now let us see what really happens inside the const block. For p2_0, iota has the value of 0 and p2_0 is defined as 1. For p2_2, iota has the value of 2 and p2_2 is defined as the result of the expression 1 << 2, which is 00000100 in binary representation. The decimal value of 00000100 is 4, which is the result and the value of p2_2. Analogously, the value of p2_4 is 16 and the value of p2_6 is 64.

Running constants.go produces the next output:

$ go run constants.go
1476
3.1415926
1
2
2^0: 1
2^2: 4
2^4: 16
2^6: 64

Having data is good but what happens when you have lots of similar data? Do you need to have lots of variables to hold this data or is there a better way to do so? Go answers these questions by introducing arrays and slices.