-->

Go 1.18

Posted by : at

Category : guides   go


The long-awaited Go 1.18 is just around the corner, and it is probably the most discussed update to Go in a long time. There are some major new things added to the language, with Generics standing out the most. 

Many of the new stuff being added is missed because everybody is focused on generics, so let’s make a quick overview of the all changes that are coming. There are changes that I feel are important to know about in the coming update, that you don’t see mentioned that much.

For some of the Major features, I have an in-depth article that you are welcome to read if you want a deeper look at the feature.

All images are drawn by Percy Bolmér. Gopher by Takuya Ueda, Original Go Gopher by Renée French (CC BY 3.0)

Generics

A visual representation of generics

As already mentioned earlier, Go is finally getting generics. This seems to be a topic that can upset developers, some developers seem to love the idea, some seem to hate it.

Generics is a way of allowing a function to accept multiple different data types. This is useful when you have to perform the same thing for many different types.

If you would rather watch my video about this you can find it here.

The lack of generics in Go has previously been solved by, duplicate functions per data type, or the use of an empty interface{} that is typecast with a massive switch to handle the needed data types. These two workarounds are not uncommon solutions to the lack of generics. These solutions, or, kind of hacks can be removed with the release of 1.18.

Gone are the days of the []interface{} hack - Generic Developer

Imagine you have to summarize the values for a slice of Integers and a slice of Floats. This would require you to have two duplicate functions, the functions would be the same, an for range that goes through and adds the values and return the result. The only difference would be the defined input parameters data type.

Before generics, this required a summary function specific to each data type like the gist below.

main.go - CountTotal for different data types solved with dupelicate functions

With generics, all those three summary functions can be done with the same function instead.

Let’s take a look at how this looks when solved with generics instead.

main.go - A generic solution for summarizing the total values

That is a massive improvement according to me. Not only is the amount of code reduced, but it is also easier to maintain, read, and a less complex solution.

If you want to read more about how to use generics, you can read Learning Generics in Go. In it, we cover how to use generics and what more you can do with it.

Fuzzing tests

Fuzzing is introduced in Go 1.18

Fuzzing is one of the things I like most about the update. I am surprised people are not talking more about it. It will give us the ability to generate input parameters during testing.

It might not sound like much, but it allows us to easily expand the unit tests to locate and track down more bugs. Table Driven Tests allows us to give many different inputs, but still, you won’t write a few hundred different test inputs probably, but fuzzing can allow this to be generated.

Fuzzing allows you to test thousands of different inputs, this helps finding hidden bugs, bugs you would probably not have thought of yourself to check for.

The idea about fuzzing is that by generating a bunch of different inputs to your functions, there is a higher chance of finding breaking edge cases. The fuzzing package will take in an example input to use as a base, called a seed corpus. The fuzzer will use those examples as a starting point and modify that to find values that cause your function to break.

Fuzzing will be added to the testing package, and it will be a new struct used in the same way as testing.T but instead testing.F.

An example on fuzzing from go.dev lookslike this, note how they add the GET query parameters as a seed corpus, this will allow the fuzzer to generate thousands of similar inputs.

go.dev - Example fuzzing

If you want to learn about how to use the fuzzer and write your fuzzing functions for, etc HTTP Handlers or more, then you can read my article Fuzzy Testing in Go.

Workspaces

Workspace mode allows us to replace versions and modules in a better way. Image by Percy Bolmér. Gopher by Takuya Ueda, Original Go Gopher by Renée French (CC BY 3.0)

Workspaces are released to allow developers to easily switch the version of modules to be used inside a project. The reason for this is to ease the development while working on multiple modules at the same time.

If you have been using go modules in a company environment you most likely have been forced to add a replace directive to change or force a local version of a package to be used.

The replace directive is easy to forget to remove from your go.mod file, which will break the module for other developers if pushed to the repository. Since the tooling will now use the path given in the go.mod file, which most likely won’t exist on another developer’s computer.

If you are unfamiliar with replace, you can replace the module to use inside the go.mod file by telling it to replace a certain module with either a local path or particular version, to make it grab a local fork instead of fetching the library with go get.

go.mod - Minimal replace directive.

You can see in the gist how I tell the go tooling that any time it sees github.com/programmingpercy/mymodule it should fetch that from a local path on my computer at /home/users/percy/experimental/mymodule instead of using go get

Finally, we have a remedy against replace directives in go.mod files. This is pretty big for me, I often find myself in situations working on multiple modules at the same time and making changes in them simultaneously.

To start using workspace mode as they call it, you initialize the workspace by using the regular go tooling. Similar to creating a module, you run go work init. This will create your workspace file that we can start using.

Note that workspace mode will make many of the go toolings start using the go.work file and modify it for you. The go team states that you should not push the go.work file to repositories, as this will reintroduce the problem of the replace inside go.mod files.

The workspace mode will force all modules mentioned in the go.work to be used, similar to the go.mod file. We can still use the replace directive to specify the module to use instead. This allows you to keep using the replace directive while keeping your go.mod file clean, and only .gitignore the go.work.

In the proposal, more features are mentioned, the ability to switch between different workspaces to test multiple dependency versions easily, etc. Can’t wait to try this feature out more.

Honorable Mentions

There are some changes worth a mention, but not big enough to have their chapter.

  • any - If you start seeing any appear in go codebases don’t panic. This is a new predeclared alias for interface{}

  • comparable - An predeclared alias for an interface that contains all the types that can be compared using == and !=. This is connected to generics and to be used as a constraint.

  • net/netip - Seems that we will get a new package for handling IP addresses. I have done a lot of networking in Go, and it has been painful to handle IP addresses. It looks like I was not the only one to experience this, lets hope this solution is better.

  • strings.Cut - The improvement I never knew we needed. The strings package comes with a new function, Cut which will find a separator and return anything found before and after the separator. It will also return a bool indicating if the separator was found.

IP:PORT – I’m looking at you

Conclusion

This update will bring many welcome changes. The go team has been working hard, we can tell by the many great changes.

I am particularly fond of the introduction to workspaces and fuzzing.

The go language is maturing and as a Gopher, I am proud to watch it grow up.

If you like my writing, make sure you check out the in-depth articles on the major topics if you want to learn how to use the new features.  You should read about Learning Generics in Go and Fuzzy Testing in Go.

What are you waiting for, download the 1.18 update already and start using all the new shiny swag!

Fuzzy Testing in Go »


About Programming Percy
Programming Percy

Hey, I'm Percy Bolmér. I'm a software engineer, writer and tech enthusiast. I've been professionally building software for 7+ years, and absoluetly love sharing any ideas I come across.

Email : programmingpercy@gmail.com

Website : https://programmingpercy.tech

About Percy Bolmér

Hey, I'm Percy Bolmér. I'm a software engineer, writer and tech enthusiast. I've been professionally building software for 7+ years, and absoluetly love sharing any ideas I come across.

Useful Links