Modernize Go with golangci-lint v2.6.0
TL;DR#
golangci-lint v2.6.0 adds the new modernize analyzer. It surfaces suggestions to adopt modern Go features from the standard library (e.g., strings.CutPrefix, slices.Contains, maps.Clone) and language (any). Previously the tool was available as a separate binary, but it’ll receive much more exposure now being included in golangci-lint.
What is modernize?#
The modernize analyzer suggests clearer, more idiomatic code by using newer Go features. Each diagnostic includes a suggested fix designed to be behavior-preserving. Many improvements rely on Go ≥1.21 features. If your module uses an older go version, you’ll see fewer suggestions and some fixes won’t apply cleanly.
A few examples#
Replace manual prefix handling with strings.CutPrefix#
Before:
if strings.HasPrefix(s, "llama") {
s = s[len("llama"):]
}
After:
if after, ok := strings.CutPrefix(s, "llama"); ok {
s = after
}
Replace hand-rolled membership checks with slices.Contains#
Before:
found := false
for _, v := range xs {
if v == needle {
found = true
break
}
}
After:
found := slices.Contains(xs, needle)
Replace manual map clone loops with maps.Clone#
Before:
dst := make(map[string]int, len(src))
for k, v := range src {
dst[k] = v
}
After:
dst := maps.Clone(src)
Prefer any over interface#
Before:
var x interface{}
After:
var x any
How to enable it#
With golangci-lint (recommended)#
In .golangci.yml:
linters:
enable:
- modernize
Or via CLI:
golangci-lint run --enable modernize
Optionally apply fixes automatically (where supported):
golangci-lint run --enable modernize --fix
Real world example#
I originally enabled modernize for CoreDNS in coredns/coredns#7536. I went through the analyser findings and applied fixes. To keep future code changes from diverging from modernize, I added a separate CI step that failed if modernize produced a non-empty diff. This worked fine.
Now with golangci-lint v2.6.0 out, I refactored this in coredns/coredns#7645. The reflecttypefor had a number of changes that will need to be addressed separately. Nice and clean now.