Golang Tag Alignment
Tag Alignment is way more easier subject than the Field Alignment and structure size optimization that I've covered in the previous post.
You can use tags for additional functionalities on the struct's fields, commonly used by the encoders.
[1] Go offers struct tags which are discoverable via reflection. These enjoy a wide range of use in the standard library in the JSON/XML and other encoding packages.
Tagged struct can look as follows:
type Address struct {
Name string `yaml:"name" json:"name" xml:"name"`
Street string `yaml:"street" json:"street" xml:"street"`
ZipCode string `yaml:"zipCode" json:"zipCode" xml:"zipCode"`
City string `yaml:"city" json:"city" xml:"city"`
}
Such a struct is totally valid and compiles successfully, however tags (yaml, json and xml) are not sorted and not aligned, thus it might be harder to read.
What's the golangci-lint outcome on that file?
Problem
When running a linter you can see errors that might look like these:
golangci-lint run ./...
tags.go:4:17: tag is not aligned, should be: json:"name" xml:"name" yaml:"name" (tagalign)
Name string `yaml:"name" json:"name" xml:"name"`
^
tags.go:5:17: tag is not aligned, should be: json:"street" xml:"street" yaml:"street" (tagalign)
Street string `yaml:"street" json:"street" xml:"street"`
^
tags.go:6:17: tag is not aligned, should be: json:"zipCode" xml:"zipCode" yaml:"zipCode" (tagalign)
ZipCode string `yaml:"zipCode" json:"zipCode" xml:"zipCode"`
^
tags.go:7:17: tag is not aligned, should be: json:"city" xml:"city" yaml:"city" (tagalign)
City string `yaml:"city" json:"city" xml:"city"`
tagalign command that is being used by the golangci-lint to detect these issues reports where the error is and how it should looks like when fixed (that's a way more better output than from the govet).
Solution
The solution comes also from the tagalign package:
[2] TagAlign is used to align and sort tags in Go struct. It can make the struct more readable and easier to maintain.
We can fix this in two ways:
Using the --fix param for the golangci-lint command (since the version v1.53):
golangci-lint run --fix ./...
Using tagalign in the standalone mode.
// Install tagalign.
go install github.com/4meepo/tagalign/cmd/tagalign@latest
// Align tags.
tagalign -fix ./...
// Align and sort tags.
tagalign -fix -sort ./...
More details on additional params for tagalign you can find directly on the tagalign GH page.
How to configure tagalign with the golangci-lint please check the latter documentation.
Our sorted Address struct now looks as follows:
type Address struct {
Name string `json:"name" xml:"name" yaml:"name"`
Street string `json:"street" xml:"street" yaml:"street"`
ZipCode string `json:"zipCode" xml:"zipCode" yaml:"zipCode"`
City string `json:"city" xml:"city" yaml:"city"`
}
Sources
Docs:
Quotations: