Reader small image

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

Product typeBook
Published inMar 2024
Reading LevelBeginner
PublisherPackt
ISBN-139781803243054
Edition2nd Edition
Languages
Right arrow
Author (1)
Samantha Coyle
Samantha Coyle
author image
Samantha Coyle

Samantha Coyle, a Software Engineer at Diagrid, specializes in Go for cloud-native developer tooling, abstracting application development challenges. Committed to Open Source, she contributes to projects like Dapr and Testcontainers. She boasts a rich history in retail computer vision solutions and successfully stabilized industrial edge use cases with testing and diverse deployments for biopharma data pipelines. Her expertise extends to being CKAD certified and reviewing Go textbooks. She is passionate about empowering early-career, diverse professionals. Samantha is in a family of gophers, and enjoys GopherCon with her brother and identical twin sister. She's a seasoned speaker, having presented at various conferences, including GopherCon.
Read more about Samantha Coyle

Right arrow

Complex Types

Overview

This chapter introduces Go’s more complex types. This will build on what we learned in the previous chapter regarding Go’s core types. These complex types are indispensable when you build more complex software as they allow you to logically group related data together. This ability to group data makes code easier to understand, maintain, and fix.

By the end of this chapter, you will be able to use arrays, slices, and maps to group data together. You will learn to create custom types based on the core types. You will also learn to use structs to create structures composed of named fields of any other types and explain the importance of interface{}.

Technical requirements

For this chapter, you'll require Go version 1.21 or higher. The code for this chapter can be found at: https://github.com/PacktPublishing/Go-Programming-From-Beginner-to-Professional-Second-Edition-/tree/main/Chapter04.

Introduction

In the previous chapter, we covered Go’s core types. These types are critical to everything you do in Go, but it can be challenging to model more complex data. In modern computer software, we want to be able to group data and logic where possible. We also want to be able to make our logic reflect the real-world solutions we’re building.

If you were building software for cars, you would ideally want a custom type that embodies a car. This type should be named “car” and it should have properties that can store information about what kind of car it is. The logic that affects the car, such as starting and stopping, should be associated with the car type. If we had to manage more than one car, we would need to be able to group all the cars.

In this chapter, we’ll learn about the features in Go that allow us to model the data part of this challenge. Then, in the next chapter, we’ll solve the behavior part. By using custom types...

Collection types

If you were dealing with a single email address, you would define a string variable to hold that value for you. Now, think about how you would structure your code if you needed to deal with between 0 and 100 email addresses. You could define a separate variable for each email address, but Go has something else we can use.

When dealing with lots of similar data, we put it in a collection. Go’s collection types are arrays, slices, and maps. Go’s collection types are strongly typed and easy to loop over, but they each have unique qualities that mean they are better suited to different use cases.

Arrays

Go’s most basic collection type is an array. When you define an array, you must specify what type of data it may contain and how big the array is in the following form: [<size>]<type>. For example, [10]int is an array of size 10 that contains integers, while [5]string is an array of size 5 that contains strings. The key to making this an array is specifying the size. If your definition didn’t have the size, it would seem like it works, but it would not be an array – it’d be a slice. A slice is a different, more flexible, type of collection that we’ll look at after arrays. You can set the element values to be any type, including pointers and arrays.

You can initialize arrays with data using the following form: [<size>]<type>{<value1>,<value2>,…<valueN>}. For example, [5]string{1} would initialize the array with the first value as 1, while [5]string{9,9,9,9,9} would fill the array with the value...

Slices

Arrays are great, but their rigidity around size can cause issues. If you wanted to create a function that accepted an array and sorted the data in it, it could only work for one size of an array. That requires you to create a function for each size of an array. This strictness around size makes working with arrays feel like a hassle and unengaging. The flip side of arrays is that they are an efficient way of managing sorted collections of data. Wouldn’t it be great if there were a way to get the efficiency of arrays but with more flexibility? Go gives you this in the form of slices.

A slice is a thin layer around arrays that lets you have a sorted numeric indexed collection without having to worry about the size. Underneath the thin layer is still a Go array, but Go manages all the details, such as how big an array to use. You use a slice just like you would an array; it only holds values of one type, you can read and write to each element using [ and ], and they...

Simple custom types

You can create custom types using Go’s simple types as a starting point. The notation is type <name> <type>. If we were to create an ID type based on a string, this would look like type id string. The custom type acts the same as the type you based it on, including getting the same zero value and having the same abilities to compare with other values of the same type. A custom type is not compatible with its base type, but you can convert your custom type back into the type it’s based on to allow for interaction.

Exercise 4.16 – Creating a simple custom type

In this exercise, we’ll define a map and then delete an element from it using user input and a simple custom type. Then, we’ll print the now possibly smaller map to the console. Let’s get started:

  1. Create a new folder and add a file named main.go to it.
  2. In main.go, add the package and imports:
    package main
    import "fmt"
  3. Define...

Structs

Collections are perfect for grouping values of the same type and purpose together. There is another way of grouping data together in Go for a different purpose. Often, a simple string, number, or Boolean doesn’t fully capture the essence of the data you’ll have.

For example, for our user map, a user was represented by their unique ID and their first name. That is rarely going to be enough detail to be able to work with user records. The data you could capture about a person is almost infinite, such as their given, middle, and family names. Their preferred prefix and suffix, their date of birth, their height, weight, or where they work can also be captured. It would be possible to store this data in multiple maps, all with the same key, but that is hard to work with and maintain.

The ideal thing to do is to collect all these different bits of data into a single data structure that you can design and control. That’s what Go’s struct type is:...

Summary

In this chapter, we got into advanced uses of variables and types in Go. Real-world code gets complicated quickly because the real world is complicated. Being able to model the data accurately and keep that data logically organized in your code helps reduce the complexity of your code to a minimum.

You now know how to group similar data, either in a fixed-length ordered list using an array, in a dynamic-length ordered list using a slice, or in a key-value hash using a map.

We learned to go beyond Go’s core types and start to create custom types based either directly on the core types or by creating a struct, which is a collection of other types held in a single type and value.

There are times when you’ll have type mismatches, so Go gives us the ability to convert compatible types so that they can interact in a type-safe way.

Go also lets us break free of its type-safety rules and gives us full control. By using type assertions, we can accept any type...

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 2024Publisher: PacktISBN-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.
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
Samantha Coyle

Samantha Coyle, a Software Engineer at Diagrid, specializes in Go for cloud-native developer tooling, abstracting application development challenges. Committed to Open Source, she contributes to projects like Dapr and Testcontainers. She boasts a rich history in retail computer vision solutions and successfully stabilized industrial edge use cases with testing and diverse deployments for biopharma data pipelines. Her expertise extends to being CKAD certified and reviewing Go textbooks. She is passionate about empowering early-career, diverse professionals. Samantha is in a family of gophers, and enjoys GopherCon with her brother and identical twin sister. She's a seasoned speaker, having presented at various conferences, including GopherCon.
Read more about Samantha Coyle