Reader small image

You're reading from  Mastering Go - Fourth Edition

Product typeBook
Published inMar 2024
Reading LevelExpert
PublisherPackt
ISBN-139781805127147
Edition4th Edition
Languages
Right arrow
Author (1)
Mihalis Tsoukalos
Mihalis Tsoukalos
author image
Mihalis Tsoukalos

Mihalis Tsoukalos holds a BSc in Mathematics from the University of Patras and an MSc in IT from University College London. His previous books Go Systems Programming and Mastering Go have become must-reads for UNIX and Linux systems professionals. He works as a UNIX systems engineer and a technical author. He enjoys writing technical articles and has written for Sys Admin, MacTech, C/C++ Users Journal, USENIX ;login:, Linux Journal, Linux User and Developer, Linux Format, and Linux Voice. His research interests include time series data mining, time series indexing, and databases.
Read more about Mihalis Tsoukalos

Right arrow

Basic Go Data Types

Data is stored and manipulated in variables—all Go variables should have a data type that is either determined implicitly or declared explicitly. Knowing the built-in data types of Go allows you to understand how to manipulate simple data values and construct more complex data structures when simple data types are not enough or not efficient for a job. Go being a statically typed and compiled programming language allows the compiler to perform various optimizations and checks prior to program execution.

The first part of this chapter is all about the basic data types of Go, and the second part logically follows, covering the data structures that allow you to group data of the same data type, which are arrays and the much more powerful slices.

But let us begin with something more practical: imagine that you want to read data as command line arguments. How can you be sure that what you have read was what you expected? How can you handle error situations...

The error data type

Go provides a special data type, named error, for representing error conditions and error messages—in practice, this means that Go treats errors as values. To program successfully in Go, you should be aware of the error conditions that might occur with the functions and methods you are using and handle them accordingly.

As you already know from the previous chapter, Go follows a particular convention concerning error values: if the value of an error variable is nil, then there is no error. As an example, let us consider strconv.Atoi(), which is used for converting a string value into an int value (Atoi stands for ASCII to Int). As specified by its signature, strconv.Atoi() returns (int, error). Having an error value of nil means that the conversion was successful and that you can use the int value if you want. Having an error value that is not nil means that the conversion was unsuccessful and that the string input is not a valid int value.

...

Numeric data types

Go supports integer, floating-point, and complex number values in various versions depending on the memory space they consume—this saves memory and computing time. Integer data types can be either signed or unsigned, which is not the case for floating-point numbers.

The table that follows lists the numeric data types of Go.

Data Type

Description

int8

8-bit signed integer

int16

16-bit signed integer

int32

32-bit signed integer

int64

64-bit signed integer

int

...

Non-numeric data types

Go has support for strings, characters, runes, dates, and times. However, Go does not have a dedicated char data type. In Go, dates and times are the same thing and are represented by the same data type. However, it is up to you to determine whether a time and date variable contains valid information or not.

We begin by explaining the string-related data types.

Strings, characters, and runes

Go supports the string data type for representing strings—strings are enclosed within either double quotes or back quotes. A Go string is just a collection of bytes and can be accessed as a whole or as an array. A single byte can store any ASCII character—however, multiple bytes are usually needed for storing a single Unicode character.

Nowadays, supporting Unicode characters is a common requirement—Go was designed with Unicode support in mind, which is the main reason for having the rune data type. A rune is an int32 value that is used...

Constants

Go supports constants, which behave like variables but cannot change their values. Constants in Go are defined with the help of the const keyword. Constants can be either global or local. However, if you are defining too many constant values with a local scope, you might need to rethink your approach.

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 numeric as the type for storing constant values because this gives Go more flexibility when dealing with constants.

Some possible uses of constants include defining configuration values such as the maximum number of connections or the TCP/IP port number used and defining physical constants such as the speed of light or the gravity...

Grouping similar data

There are times when you want to keep multiple values of the same data type under a single variable and access them using an index number. The simplest way to do that in Go is by using arrays or slices. Arrays are the most widely used data structures and can be found in almost all programming languages due to their simplicity and speed of access. Go provides an alternative to arrays that is called a slice. The subsections that follow help you understand the differences between arrays and slices so that you know which data structure to use and when. The quick answer is that you can use slices instead of arrays almost anywhere in Go, but we are also demonstrating arrays because they can still be useful and because slices are implemented by Go using arrays!

Arrays

We are going to begin our discussion about arrays by examining their core characteristics and limitations:

  • When defining an array variable, you must define its size. Otherwise, you should...

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.

A picture containing text, screenshot, rectangle, font  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 when there...

Data types and the unsafe package

The unsafe package in Go provides facilities for performing operations that break the type safety guarantees of Go. It is a powerful but potentially dangerous package, and its use is discouraged in most Go code. Therefore, the unsafe package is intended for specific situations where low-level programming is necessary, such as interfacing with non-Go code, dealing with memory layout, or implementing certain advanced features.

In this section, we are going to discuss four functions of the unsafe package that are related to strings and slices. You might not have to use any of them on a regular basis, but it is good to know about them because they provide speed when dealing with large strings or slices that take lots of memory because they deal with memory addresses directly, which might be very dangerous if you do not know what you are doing. The four functions that we are going to discuss are unsafe.StringData(), unsafe.String(), unsafe.Slice()...

Generating random numbers

Random number generation is an art as well as a research area in computer science. This is because computers are purely logical machines, and it turns out that using them to generate random numbers is extremely difficult!

Go can help you with that using the functionality of the math/rand package. Each random number generator needs a seed to start producing numbers. The seed is used for initializing the entire process and is extremely important because if you always start with the same seed, you will always get the same sequence of pseudo-random numbers. This means that everybody can regenerate that sequence, and that particular sequence will not be random after all.

However, this feature is very handy for testing purposes. In Go, the rand.Seed() function is used for initializing a random number generator.

If you are really interested in random number generation, you should start by reading the second volume of The Art of Computer Programming...

Updating the statistics application

In this section, we are going to improve the functionality and the operation of the statistics application. When there is no valid input, we are going to populate the statistics application with ten random values, which is pretty handy when you want to put lots of data in an application for testing purposes—you can change the number of random values to fit your needs. However, keep in mind that this takes place when all user input is invalid.

I have randomly generated data in the past in order to put sample data into Kafka topics, RabbitMQ queues and MySQL tables.

Additionally, we are going to normalize the data. Officially, this is called z-normalization and is helpful for allowing sequences of values to be compared more accurately. We are going to use normalization in forthcoming chapters.

The function for the normalization of the data is implemented as follows:

func normalize(data []float64, mean float64, stdDev...

Summary

In this chapter, we learned about the basic data types of Go, including numerical data types, strings, and errors. Additionally, we learned how to group similar values using arrays and slices. Lastly, we learned about the differences between arrays and slices and why slices are more versatile than arrays, as well as pointers and generating random numbers and strings in order to generate random data.

One thing that you should remember from this chapter is that a slice is empty if its length is equal to 0. On the other hand, a slice is nil if it is equal to nil—this means that it points to no memory address. The var s []string statement creates a nil slice without allocating any memory. A nil slice is always empty—the reverse is not always true.

As far as Go strings are concerned, remember that double quotes define an interpreted string literal whereas back quotes define a raw string literal. Most of the time, you need double quotes.

Last, keep in mind...

Exercises

Try to do the following exercises:

  • Correct the error in typedConstants.go.
  • Create and test a function that concatenates two arrays into a new slice.
  • Create a function that concatenates two arrays into a new array. Do not forget to test it with various types of input.
  • Create a function that concatenates two slices into a new array.
  • Run go doc errors Is in order to learn about errors.Is() and try to create a small Go program that uses it. After that, modify error.go to use errors.Is().
  • Modify stats.go in order to accept the number of randomly generated values as a command line argument.
  • Modify stats.go in order to always use randomly generated data.

Additional resources

Join our community on Discord

Join our community’s Discord space for discussions with the authors and other readers:

https://discord.gg/FzuQbc8zd6

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering Go - Fourth Edition
Published in: Mar 2024Publisher: PacktISBN-13: 9781805127147
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.
undefined
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

Author (1)

author image
Mihalis Tsoukalos

Mihalis Tsoukalos holds a BSc in Mathematics from the University of Patras and an MSc in IT from University College London. His previous books Go Systems Programming and Mastering Go have become must-reads for UNIX and Linux systems professionals. He works as a UNIX systems engineer and a technical author. He enjoys writing technical articles and has written for Sys Admin, MacTech, C/C++ Users Journal, USENIX ;login:, Linux Journal, Linux User and Developer, Linux Format, and Linux Voice. His research interests include time series data mining, time series indexing, and databases.
Read more about Mihalis Tsoukalos