DEV Community

Ville Vesilehto
Ville Vesilehto

Posted on • Originally published at ville.dev

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.

Example from golangci-lint with modernize linter

A few examples

Replace manual prefix handling with strings.CutPrefix

Before:

if strings.HasPrefix(s, "llama") { s = s[len("llama"):] } 
Enter fullscreen mode Exit fullscreen mode

After:

if after, ok := strings.CutPrefix(s, "llama"); ok { s = after } 
Enter fullscreen mode Exit fullscreen mode

Replace hand-rolled membership checks with slices.Contains

Before:

found := false for _, v := range xs { if v == needle { found = true break } } 
Enter fullscreen mode Exit fullscreen mode

After:

found := slices.Contains(xs, needle) 
Enter fullscreen mode Exit fullscreen mode

Replace manual map clone loops with maps.Clone

Before:

dst := make(map[string]int, len(src)) for k, v := range src { dst[k] = v } 
Enter fullscreen mode Exit fullscreen mode

After:

dst := maps.Clone(src) 
Enter fullscreen mode Exit fullscreen mode

Prefer any over interface{}

Before:

var x interface{} 
Enter fullscreen mode Exit fullscreen mode

After:

var x any 
Enter fullscreen mode Exit fullscreen mode

How to enable it

With golangci-lint (recommended)

In .golangci.yml:

linters: enable: - modernize 
Enter fullscreen mode Exit fullscreen mode

Or via CLI:

golangci-lint run --enable modernize 
Enter fullscreen mode Exit fullscreen mode

Optionally apply fixes automatically (where supported):

golangci-lint run --enable modernize --fix 
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)