首页 > 解决方案 > go lint 工具范围关闭检测

问题描述

一直在尝试将gonnel用于一些隧道。试图打开 2 个隧道,然后当它们关闭时,我注意到日志包说试图关闭同一个隧道两次。通过查看代码,似乎(其中一个)问题是: 在此处输入图像描述

我想我会利用 staticcheck、golangci-lint 甚至去 vet 让它突出这个问题,这样我就可以更有信心进行修复。但是,当我运行这些工具时,会得到以下输出:

golangci-lint: 在此处输入图像描述

去看兽医:

在此处输入图像描述

静态检查:

在此处输入图像描述

还尝试使用 -loopclosure 运行 go vet,但我仍然没有得到任何输出。难道其中一个工具不应该说 go func 需要将迭代器变量作为参数传递吗?如果有帮助,我正在运行 go 1.14.3 darwin/amd64,并且还尝试在 goland 中导入代码,但我没有收到该段代码的检查警告。我有一种感觉,我可能做错了什么,你能发现它是什么吗?

谢谢!

标签: gostatic-analysislintlinter

解决方案


是,对的。这个问题在 Gophers 中很常见(作为 goroutine 运行的闭包会发生什么?)!

去兽医的问题:

  1. https://github.com/golang/go/issues/21412
  2. https://github.com/golang/go/issues/16520

因此,您似乎看不到 go vet 的输出,因为 goroutine 在一个if块中。您可以尝试不使用if障碍物吗?我认为您的问题更相关问题 21412


对于golangci/govet 也是如此

引用golangci/govet/rangeloop.go的代码:

This file contains the code to check range loop variables bound inside function
literals that are deferred or launched in new goroutines. We only check
instances where the defer or go statement is the last statement in the loop
body, as otherwise, we would need whole-program analysis.

另外,我的建议是检查隧道是否打开,然后只关闭它。您可能会重复条目,所以再次有可能出现一些问题。并首先修复作为 goroutine 错误运行的闭包。

因此,这是一个示例,其中if块是如何go vet工作的差异化因素。

  • 使用if块,go vet不返回任何内容
package main

import (
        "fmt"
        "sync"
)

func main() {
        fruits := []string{"orange", "apple"}
        var wg sync.WaitGroup
        for _, fruit := range fruits {
                if true {
                        wg.Add(1)
                        go func() {
                                fmt.Println(fruit)
                                wg.Done()
                        }()
                }
        }
        wg.Wait()
}
  • 没有if阻塞,go vet返回loop variable fruit captured by func literal
package main

import (
        "fmt"
        "sync"
)

func main() {
        fruits := []string{"orange", "apple"}
        var wg sync.WaitGroup
        for _, fruit := range fruits {
                wg.Add(1)
                go func() {
                        fmt.Println(fruit)
                        wg.Done()
                }()
        }
        wg.Wait()
}

推荐阅读