Movatterモバイル変換


[0]ホーム

URL:


loopclosure

package
v0.37.0Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2025 License:BSD-3-ClauseImports:11Imported by:309

Details

Repository

cs.opensource.google/go/x/tools

Links

Documentation

Overview

Package loopclosure defines an Analyzer that checks for references toenclosing loop variables from within nested functions.

Analyzer loopclosure

loopclosure: check references to loop variables from within nested functions

This analyzer reports places where a function literal references theiteration variable of an enclosing loop, and the loop calls the functionin such a way (e.g. with go or defer) that it may outlive the loopiteration and possibly observe the wrong value of the variable.

Note: An iteration variable can only outlive a loop iteration in Go versions <=1.21.In Go 1.22 and later, the loop variable lifetimes changed to create a newiteration variable per loop iteration. (See go.dev/issue/60078.)

In this example, all the deferred functions run after the loop hascompleted, so all observe the final value of v [<go1.22].

for _, v := range list {    defer func() {        use(v) // incorrect    }()}

One fix is to create a new variable for each iteration of the loop:

for _, v := range list {    v := v // new var per iteration    defer func() {        use(v) // ok    }()}

After Go version 1.22, the previous two for loops are equivalentand both are correct.

The next example uses a go statement and has a similar problem [<go1.22].In addition, it has a data race because the loop updates vconcurrent with the goroutines accessing it.

for _, v := range elem {    go func() {        use(v)  // incorrect, and a data race    }()}

A fix is the same as before. The checker also reports problemsin goroutines started by golang.org/x/sync/errgroup.Group.A hard-to-spot variant of this form is common in parallel tests:

func Test(t *testing.T) {    for _, test := range tests {        t.Run(test.name, func(t *testing.T) {            t.Parallel()            use(test) // incorrect, and a data race        })    }}

The t.Parallel() call causes the rest of the function to executeconcurrent with the loop [<go1.22].

The analyzer reports references only in the last statement,as it is not deep enough to understand the effects of subsequentstatements that might render the reference benign.("Last statement" is defined recursively in compoundstatements such as if, switch, and select.)

See:https://golang.org/doc/go_faq.html#closures_and_goroutines

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{Name:     "loopclosure",Doc:analysisutil.MustExtractDoc(doc, "loopclosure"),URL:      "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/loopclosure",Requires: []*analysis.Analyzer{inspect.Analyzer},Run:      run,}

Functions

This section is empty.

Types

This section is empty.

Source Files

View all Source files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f orF : Jump to
y orY : Canonical URL
go.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.Learn more.

[8]ページ先頭

©2009-2025 Movatter.jp