Golang Release 1.22: version

- 4 minutes read - 818 words

How to use the new package in Go standard library to work with Go version strings.

With the release of Go 1.22, the Go standard library introduced several new features. As you might have noticed in articles related to the previous release, here we mostly concentrate on the new exciting packages and features that they give us. This article will start this journey, by providing a deeper look into the implementation of the version package in Go.

Lang

The first function we are ready to examine is the Lang function. This function provides a cleaned, valid Go version as a string. In case it can’t determine the actual version, due to an invalid state of the string value, it will return an string as a result.

Lang function

func Lang(x string) string

As we can see the function signature above, function expects one argument, a string, that represents a Go version. An output should be also one value, a string, as a cleaned Go version.

Lang function examples

package main

import (
	"fmt"
	"go/version"
)

func main() {
	fmt.Println(version.Lang("go1.0"))      // go1
	fmt.Println(version.Lang("go1"))        // go1
	fmt.Println(version.Lang("go1.22.4"))   // go1.22
	fmt.Println(version.Lang("go1.22.3"))   // go1.22
	fmt.Println(version.Lang("go1.22.2"))   // go1.22
	fmt.Println(version.Lang("go1.22.rc1")) //
	fmt.Println(version.Lang("go1.22rc1"))  // go1.22
	fmt.Println(version.Lang("1.22"))       //
	fmt.Println(version.Lang("wrong"))      //
	fmt.Println(version.Lang(""))           //
}

In the example above, we can see how the Lang function adapt the Go version string. It removes all minor versions and appearance of “release candide” phrase, and present them in the end as an official Go versions that we experienced in the past (and we might experience in the future). In cases where we provided an invalid, or empty string, the ending result will be also an empty string, as the Lang function can’t find the actual version name.

One interesting point, not just for the Long function, but, as you will see, for all functions in this package, to consider some string as a valid Go version, it needs to have a prefix go.

IsValid

The next function we are examining is the IsValid function. This function checks a string with a potential Go version and returns a boolean result that tells us if the version is valid or not.

IsValid function

func IsValid(x string) bool

As we can see the function signature above, function expects one argument, a string, that represents a Go version. An output should be a bool value, which tells us if the Go version is valid or not.

IsValid function examples

package main

import (
	"fmt"
	"go/version"
)

func main() {
	fmt.Println(version.IsValid("go1.0"))      // true
	fmt.Println(version.IsValid("go1"))        // true
	fmt.Println(version.IsValid("go1.22.4"))   // true
	fmt.Println(version.IsValid("go1.22.3"))   // true
	fmt.Println(version.IsValid("go1.22.2"))   // true
	fmt.Println(version.IsValid("go1.22.rc1")) // false
	fmt.Println(version.IsValid("go1.22rc1"))  // true
	fmt.Println(version.IsValid("1.22"))       // false
	fmt.Println(version.IsValid("wrong"))      // false
	fmt.Println(version.IsValid(""))           // false
}

In the example above, we can see how the IsValid function checks validity of Go version string. In a way it represents a subcase of the Lang function: wherever we got an empty string in the Lang function, we got false as the result of the IsValid function.

Compare

Finally, with the function Compare, we are showing the complete picture of the version package. This function provides the complex functionality for comparing different Go version in a spirit of other examples of the Compare function.

Compare function

// Compare returns
//
//	-1 if x is less than y,
//	 0 if x equals y,
//	+1 if x is greater than y.
// ...
func Compare(x, y string) int

In the function signature, we can see that the Compare function accepts two strings as arguments, where both of them represent Go versions. The result is an integer value, which can be -1, 0 or 1, depending od the comparison result.

Compare function examples

package main

import (
	"fmt"
	"go/version"
)

func main() {
	fmt.Println(version.Compare("go1.0", "go1"))           // 0
	fmt.Println(version.Compare("go1.1", "go1.1.0"))       // 0
	fmt.Println(version.Compare("go1", ""))                // 1
	fmt.Println(version.Compare("", ""))                   // 0
	fmt.Println(version.Compare("", "go1"))                // -1
	fmt.Println(version.Compare("go1.22.4", "go1.22.3"))   // 1
	fmt.Println(version.Compare("go1.22.2", "go1.22.3"))   // -1
	fmt.Println(version.Compare("go1.22.2", "go1.22rc1"))  // 1
	fmt.Println(version.Compare("go1.22rc2", "go1.22rc1")) // 1
	fmt.Println(version.Compare("go1.22.4", "go1.21.4"))   // 1
	fmt.Println(version.Compare("go1.22rc1", "go1.22rc1")) // 1
}

In the examples above, we can see how the Compare function actually works. First, it can find equality for two same versions, even if they are written in a different ways (the first two examples). Second, we can see that invalid versions are always considered as lower versions than any valid ones. So, we should be careful here with the comparison, as initial version validation might be important to do.

Finally, for the correct versions, the Compare function is able to determine which one of them is a higher one, and provides such a result. This is not only applied for minor versions, but also for release candidate versions, as we can see in the last examples.

Conclusion

New version of Golang, 1.22, delivered many new updates, affecting standard library as well. In this article we checked how some functions from version packages work. Those new functions give us now possibility to validate and compare different Go version strings.

Useful Resources

comments powered by Disqus