如何避免烦人的错误提示“声明但未使用”?

huangapple go评论107阅读模式
英文:

How to avoid annoying error "declared and not used"

问题

我正在学习Go语言,但我觉得有点烦人的是,在编译时我不能留下任何未使用的变量或包。

这真的让我进展缓慢。例如,我只是想声明一个新的包,并计划稍后使用它,或者只是取消注释一些命令进行测试。我总是会遇到错误,需要去注释掉所有这些使用。

有没有办法在Go中避免这种检查?

英文:

I'm learning Go but I feel it is a bit annoying that when compiling, I should not leave any variable or package unused.

This is really quite slowing me down. For example, I just wanted to declare a new package and plan to use it later or just uncomment some command to test. I always get the error and need to go comment all of those uses.

Is there any way to avoid this kind of check in Go?

答案1

得分: 355

这个错误是为了强迫你编写更好的代码,并确保使用你声明或导入的所有内容。这样可以更容易阅读其他人编写的代码(你可以确保所有声明的变量都会被使用),并避免一些可能的死代码。

但是,如果你真的想跳过这个错误,你可以使用空白标识符_):

package main

import (
    _ "fmt" // 导入但未使用:"fmt"
)

func main() {
    i := 1 // 声明但未使用的变量 i
}

变成:

package main

import (
    _ "fmt" // 不再报错
)

func main() {
    i := 1 // 不再报错
    _ = i
}

正如下面的评论中 kostix 所说,你可以在常见问题解答中找到 Go 团队的官方立场:

未使用的变量可能表示存在 bug,而未使用的导入只会减慢编译速度。如果在代码树中累积了足够多的未使用导入,编译速度会变得非常慢。出于这些原因,Go 不允许这两种情况。

英文:

That error is here to force you to write better code, and be sure to use everything you declare or import. It makes it easier to read code written by other people (you are always sure that all declared variables will be used), and avoid some possible dead code.

But, if you really want to skip this error, you can use the blank identifier (_) :

package main

import (
    "fmt" // imported and not used: "fmt"
)

func main() {
    i := 1 // i declared and not used
}

becomes

package main

import (
    _ "fmt" // no more error
)

func main() {
    i := 1 // no more error
    _ = i
}

As said by kostix in the comments below, you can find the official position of the Go team in the FAQ:

> The presence of an unused variable may indicate a bug, while unused imports just slow down compilation. Accumulate enough unused imports in your code tree and things can get very slow. For these reasons, Go allows neither.

答案2

得分: 54

我在两年前学习Go语言时遇到了这个问题,所以我声明了自己的函数。

// UNUSED函数允许在Go程序中包含未使用的变量
func UNUSED(x ...interface{}) {}

然后你可以这样使用它:

UNUSED(x)
UNUSED(x, y)
UNUSED(x, y, z)

它的好处是,你可以将任何东西传递给UNUSED函数。

这个方法比下面的方法好吗?

_, _, _ = x, y, z

这取决于你自己的选择。

英文:

I ran into this while I was learning Go 2 years ago, so I declared my own function.

// UNUSED allows unused variables to be included in Go programs
func UNUSED(x ...interface{}) {}

And then you can use it like so:

UNUSED(x)
UNUSED(x, y)
UNUSED(x, y, z)

The great thing about it is, you can pass anything into UNUSED.

Is it better than the following?

_, _, _ = x, y, z

That's up to you.

答案3

得分: 52

你可以使用一个简单的“null函数”来实现这个,例如:

func Use(vals ...interface{}) {
    for _, val := range vals {
        _ = val
    }
}

你可以这样使用它:

package main

func main() {
    a := "声明但未使用"
    b := "另一个声明但未使用"
    c := 123

    Use(a, b, c)
}

还有一个专门的包可以实现这个功能,这样你就不需要每次都定义Use函数了:

import (
    "github.com/lunux2008/xulu"
)

func main() {
    // [..]

    xulu.Use(a, b, c)
}

希望对你有帮助!

英文:

You can use a simple "null function" for this, for example:

func Use(vals ...interface{}) {
	for _, val := range vals {
		_ = val
	}
}

Which you can use like so:

package main

func main() {
    a := "declared and not used"
    b := "another declared and not used"
    c := 123

    Use(a, b, c)
}

There's also a package for this so you don't have to define the Use function every time:

import (
  "github.com/lunux2008/xulu"
)

func main() {
  // [..]

  xulu.Use(a, b, c)
}

答案4

得分: 38

根据常见问题解答

有人要求添加一个编译器选项来关闭这些检查,或者至少将其降级为警告。但是,没有添加这样的选项,因为编译器选项不应该影响语言的语义,并且Go编译器只报告阻止编译的错误,而不是警告。

没有警告的原因有两个。首先,如果值得抱怨,就值得在代码中修复。(如果不值得修复,就不值得提及。)其次,编译器生成警告会鼓励实现在可能导致编译嘈杂的弱案例上发出警告,从而掩盖应该修复的真正错误。

出于各种原因,我不一定同意这个观点,不值得深入讨论。事实就是如此,而且在不久的将来不太可能改变。

对于包,有一个goimports工具,它会自动添加缺失的包并删除未使用的包。例如:

# 安装
$ go get golang.org/x/tools/cmd/goimports

# -w 用于将源文件写入磁盘而不是标准输出
$ goimports -w my_file.go

你应该能够从任何像样的编辑器中运行这个命令,例如Vim:

:!goimports -w %

goimports页面列出了其他编辑器的一些命令,并且通常可以在保存缓冲区时自动运行它。

请注意,goimports还会运行gofmt


正如之前提到的,对于变量,最简单的方法是(临时)将它们赋值给_

// 没有错误
tasty := "ice cream"
horrible := "marmite"

// 为了调试而注释掉
//eat(tasty, horrible)

_, _ = tasty, horrible
英文:

According to the FAQ:

> Some have asked for a compiler option to turn those checks off or at least reduce them to warnings. Such an option has not been added, though, because compiler options should not affect the semantics of the language and because the Go compiler does not report warnings, only errors that prevent compilation.
>
> There are two reasons for having no warnings. First, if it's worth complaining about, it's worth fixing in the code. (And if it's not worth fixing, it's not worth mentioning.) Second, having the compiler generate warnings encourages the implementation to warn about weak cases that can make compilation noisy, masking real errors that should be fixed.

I don't necessarily agree with this for various reasons not worth going into. It is what it is, and it's not likely to change in the near future.

For packages, there's the goimports tool which automatically adds missing packages and removes unused ones. For example:

# Install it
$ go get golang.org/x/tools/cmd/goimports

# -w to write the source file instead of stdout
$ goimports -w my_file.go

You should be able to run this from any half-way decent editor − for example for Vim:

:!goimports -w %

The goimports page lists some commands for other editors, and you typically set it to be run automatically when you save the buffer to disk.

Note that goimports will also run gofmt.


As was already mentioned, for variables the easiest way is to (temporarily) assign them to _ :

// No errors
tasty := "ice cream"
horrible := "marmite"

// Commented out for debugging
//eat(tasty, horrible)

_, _ = tasty, horrible

答案5

得分: 13

如果其他人很难理解这个问题,我认为用非常简单明了的方式解释可能会有所帮助。如果你有一个你不使用的变量,例如一个你已经注释掉调用的函数(一个常见的用例):

myFn := func () { }
// myFn()

你可以将一个无用/空白变量赋值给这个函数,这样它就不再是“未使用”的了:

myFn := func () { }
_ = myFn
// myFn()
英文:

In case others have a hard time making sense of this, I think it might help to explain it in very straightforward terms. If you have a variable that you don't use, for example a function for which you've commented out the invocation (a common use-case):

myFn := func () { }
// myFn()

You can assign a useless/blank variable to the function so that it's no longer unused:

myFn := func () { }
_ = myFn
// myFn()

答案6

得分: 10

一个尚未提及的角度是用于编辑代码的工具集。

使用Visual Studio Code以及来自lukehoban的名为Go的扩展程序,可以为您自动完成一些魔法操作。Go扩展程序会自动运行gofmtgolint等,并删除和添加import条目。所以至少这部分现在是自动完成的。

我承认这并不是问题的100%解决方案,但足够有用。

英文:

One angle not so far mentioned is tool sets used for editing the code.

Using Visual Studio Code along with the Extension from lukehoban called Go will do some auto-magic for you. The Go extension automatically runs gofmt, golint etc, and removes and adds import entries. So at least that part is now automatic.

I will admit its not 100% of the solution to the question, but however useful enough.

答案7

得分: 9

根据我所了解,Go编译器中的这些行看起来是需要注释掉的部分。你可以构建自己的工具链,忽略这些产生反效果的警告。

英文:

As far as I can tell, these lines in the Go compiler look like the ones to comment out. You should be able to build your own toolchain that ignores these counterproductive warnings.

答案8

得分: 7

当我在代码的其他部分工作时,我遇到了一个问题,我想临时禁用发送电子邮件的功能。

注释掉服务的使用会触发很多级联错误,所以我使用了一个条件语句:

if false {
    // 从技术上讲,svc仍然会被使用,所以不会报错
    _, err = svc.SendRawEmail(input) 
    Check(err)
}
英文:

I ran into this issue when I wanted to temporarily disable the sending of an email while working on another part of the code.

Commenting the use of the service triggered a lot of cascade errors, so instead of commenting I used a condition

if false {
    // Technically, svc still be used so no yelling
	_, err = svc.SendRawEmail(input) 
	Check(err)
}

答案9

得分: 0

我的答案是黑掉这些该死的源代码。这个补丁适用于1.19.4版本,然后你可以使用-gcflags all=-nounusederrors选项构建你的源代码(你需要在其他地方获得帮助来构建Golang源代码):

From 6eb19713fb5302ef2d5eb4af0c05e86c88d055c7 Mon Sep 17 00:00:00 2001
From: Daniel Santos <daniel.santos@pobox.com>
Date: Mon, 9 Jan 2023 21:56:03 -0600
Subject: Add -nounusedwarnings

---
 src/cmd/compile/internal/base/flag.go       |  1 +
 src/cmd/compile/internal/types2/errors.go   | 10 ++++++++++
 src/cmd/compile/internal/types2/labels.go   |  2 +-
 src/cmd/compile/internal/types2/resolver.go |  8 ++++----
 src/cmd/compile/internal/types2/stmt.go     |  4 ++--
 src/cmd/go/alldocs.go                       |  2 ++
 src/cmd/go/internal/work/build.go           |  2 ++
 src/go/types/gotype.go                      |  3 +++
 8 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go
index a363b83984..f295746f64 100644
--- a/src/cmd/compile/internal/base/flag.go
+++ b/src/cmd/compile/internal/base/flag.go
@@ -111,6 +111,7 @@ type CmdFlags struct {
 	MemProfileRate     int          "help:\"set runtime.MemProfileRate to `rate`\""
 	MutexProfile       string       "help:\"write mutex profile to `file`\""
 	NoLocalImports     bool         "help:\"reject local (relative) imports\""
+	NoUnusedErrors     bool         "help:\"no errors for unused imports and variables\""
 	Pack               bool         "help:\"write to file.a instead of file.o\""
 	Race               bool         "help:\"enable race detector\""
 	Shared             *bool        "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below
diff --git a/src/cmd/compile/internal/types2/errors.go b/src/cmd/compile/internal/types2/errors.go
index 2a3e88a2fe..0405fa26de 100644
--- a/src/cmd/compile/internal/types2/errors.go
+++ b/src/cmd/compile/internal/types2/errors.go
@@ -8,6 +8,7 @@ package types2
 
 import (
 	"bytes"
+	"cmd/compile/internal/base"
 	"cmd/compile/internal/syntax"
 	"fmt"
 	"runtime"
@@ -275,6 +276,15 @@ func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
 	check.err(at, check.sprintf(format, args...), true)
 }
 
+func (check *Checker) unusedf(at poser, format string, args ...interface{}) {
+	if base.Flag.NoUnusedErrors {
+		pos := posFor(at)
+		fmt.Printf("%s: %s, but nobody cares\n", pos, check.sprintf(format, args...))
+	} else {
+		check.softErrorf(at, format, args)
+	}
+}
+
 func (check *Checker) versionErrorf(at poser, goVersion string, format string, args ...interface{}) {
 	msg := check.sprintf(format, args...)
 	if check.conf.CompilerErrorMessages {
diff --git a/src/cmd/compile/internal/types2/labels.go b/src/cmd/compile/internal/types2/labels.go
index 6f02e2fc96..d3ae602549 100644
--- a/src/cmd/compile/internal/types2/labels.go
+++ b/src/cmd/compile/internal/types2/labels.go
@@ -35,7 +35,7 @@ func (check *Checker) labels(body *syntax.BlockStmt) {
 	for name, obj := range all.elems {
 		obj = resolve(name, obj)
 		if lbl := obj.(*Label); !lbl.used {
-			check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name)
+			check.unusedf(lbl.pos, "label %s declared but not used", lbl.name)
 		}
 	}
 }
diff --git a/src/cmd/compile/internal/types2/resolver.go b/src/cmd/compile/internal/types2/resolver.go
index 5d498b6b2b..935435b03f 100644
--- a/src/cmd/compile/internal/types2/resolver.go
+++ b/src/cmd/compile/internal/types2/resolver.go
@@ -731,15 +731,15 @@ func (check *Checker) errorUnusedPkg(obj *PkgName) {
 	}
 	if obj.name == "" || obj.name == "." || obj.name == elem {
 		if check.conf.CompilerErrorMessages {
-			check.softErrorf(obj, "imported and not used: %q", path)
+			check.unusedf(obj, "imported and not used: %q", path)
 		} else {
-			check.softErrorf(obj, "%q imported but not used", path)
+			check.unusedf(obj, "%q imported but not used", path)
 		}
 	} else {
 		if check.conf.CompilerErrorMessages {
-			check.softErrorf(obj, "imported and not used: %q as %s", path, obj.name)
+			check.unusedf(obj, "imported and not used: %q as %s", path, obj.name)
 		} else {
-			check.softErrorf(obj, "%q imported but not used as %s", path, obj.name)
+			check.unusedf(obj, "%q imported but not used as %s", path, obj.name)
 		}
 	}
 }
diff --git a/src/cmd/compile/internal/types2/stmt.go b/src/cmd/compile/internal/types2/stmt.go
index 74d4164ba9..c4255e4413 100644
--- a/src/cmd/compile/internal/types2/stmt.go
+++ b/src/cmd/compile/internal/types2/stmt.go
@@ -66,7 +66,7 @@ func (check *Checker) usage(scope *Scope) {
 		return unused[i].pos.Cmp(unused[j].pos) < 0
 	})
 	for _, v := range unused {
-		check.softErrorf(v.pos, "%s declared but not used", v.name)
+		check.unusedf(v.pos, "%s declared but not used", v.name)
 	}
 
 	for _, scope := range scope.children {
@@ -804,7 +804,7 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
 			v.used = true // avoid usage error when checking entire function
 		}
 		if !used {
-			check.softErrorf(lhs, "%s declared but not used", lhs.Value)
+			check.unusedf(lhs, "%s declared but not used", lhs.Value)
 		}
 	}
 }
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index a3c1fecb91..1f4c5c7b5c 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -179,6 +179,8 @@
 //		directory, but it is not accessed. When -modfile is specified, an
 //		alternate go.sum file is also used: its path is derived from the
 //		-modfile flag by trimming the ".mod" extension and appending ".sum".
+//	-nounusederrors
+//		do not error on unused functions, imports, variables, etc.
 //	-overlay file
 //		read a JSON config file that provides an overlay for build operations.
 //		The file is a JSON struct with a single field, named 'Replace', that
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index 5f11cdabaf..b37f1c8a01 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -135,6 +135,8 @@ and test commands:
 		directory, but it is not accessed. When -modfile is specified, an
 		alternate go.sum file is also used: its path is derived from the
 		-modfile flag by trimming the ".mod" extension and appending ".sum".
+	-nounusederrors
+		do not error on unused functions, imports, variables, etc.
 	-overlay file
 		read a JSON config file that provides an overlay for build operations.
 		The file is a JSON struct with a single field, named 'Replace', that
diff --git a/src/go/types/gotype.go b/src/go/types/gotype.go
index e8ff9658da..5a60b83346 100644
--- a/src/go/types/gotype.go
+++ b/src/go/types/gotype.go
@@ -47,6 +47,8 @@ The flags are:
 		verbose mode
 	-c
 		compiler used for installed packages (gc, gccgo, or source); default: source
+	-nounusederrors
+		treat "unused" errors as warnings
 
 Flags controlling additional output:
 
@@ -104,6 +106,7 @@ var (
 	allErrors  = flag.Bool("e", false, "report all errors, not just the first 10")
 	verbose    = flag.Bool("v", false, "verbose mode")
 	compiler   = flag.String("c", "source", "compiler used for installed packages (gc, gccgo, or source)")
+	nounusederr= flag.Bool("nounusederrors", false, "treat unused objects as warnings")
 
 	// additional output control
 	printAST      = flag.Bool("ast", false, "print AST")
-- 
2.38.2


免责声明:这不是一个全面的补丁——它只影响运行go buildcompile工具。当使用ast(树解析器)、跟踪和其他一些工具时,仍然会出现错误,因为我没有修改internal/types,只修改了cmd/compile/internal/types2——Golang源代码有点混乱。我希望他们能在某个时候进行重构,摆脱这些冗余。

英文:

My answer is to hack the f-ing sources. This patch works against 1.19.4 and then you build your sources with -gcflags all=-nounusederrors (you'll need help elsewhere in order to build Golang from sources):

tty/tty.go:98:6: hello declared but not used, but nobody cares

It doesn't suppress some unused labels and the grammar of the appended message is a bit sloppy, but nobody cares.

From 6eb19713fb5302ef2d5eb4af0c05e86c88d055c7 Mon Sep 17 00:00:00 2001
From: Daniel Santos &lt;daniel.santos@pobox.com&gt;
Date: Mon, 9 Jan 2023 21:56:03 -0600
Subject: Add -nounusedwarnings

---
 src/cmd/compile/internal/base/flag.go       |  1 +
 src/cmd/compile/internal/types2/errors.go   | 10 ++++++++++
 src/cmd/compile/internal/types2/labels.go   |  2 +-
 src/cmd/compile/internal/types2/resolver.go |  8 ++++----
 src/cmd/compile/internal/types2/stmt.go     |  4 ++--
 src/cmd/go/alldocs.go                       |  2 ++
 src/cmd/go/internal/work/build.go           |  2 ++
 src/go/types/gotype.go                      |  3 +++
 8 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go
index a363b83984..f295746f64 100644
--- a/src/cmd/compile/internal/base/flag.go
+++ b/src/cmd/compile/internal/base/flag.go
@@ -111,6 +111,7 @@ type CmdFlags struct {
 	MemProfileRate     int          &quot;help:\&quot;set runtime.MemProfileRate to `rate`\&quot;&quot;
 	MutexProfile       string       &quot;help:\&quot;write mutex profile to `file`\&quot;&quot;
 	NoLocalImports     bool         &quot;help:\&quot;reject local (relative) imports\&quot;&quot;
+	NoUnusedErrors     bool         &quot;help:\&quot;no errors for unused imports and variables\&quot;&quot;
 	Pack               bool         &quot;help:\&quot;write to file.a instead of file.o\&quot;&quot;
 	Race               bool         &quot;help:\&quot;enable race detector\&quot;&quot;
 	Shared             *bool        &quot;help:\&quot;generate code that can be linked into a shared library\&quot;&quot; // &amp;Ctxt.Flag_shared, set below
diff --git a/src/cmd/compile/internal/types2/errors.go b/src/cmd/compile/internal/types2/errors.go
index 2a3e88a2fe..0405fa26de 100644
--- a/src/cmd/compile/internal/types2/errors.go
+++ b/src/cmd/compile/internal/types2/errors.go
@@ -8,6 +8,7 @@ package types2
 
 import (
 	&quot;bytes&quot;
+	&quot;cmd/compile/internal/base&quot;
 	&quot;cmd/compile/internal/syntax&quot;
 	&quot;fmt&quot;
 	&quot;runtime&quot;
@@ -275,6 +276,15 @@ func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
 	check.err(at, check.sprintf(format, args...), true)
 }
 
+func (check *Checker) unusedf(at poser, format string, args ...interface{}) {
+	if base.Flag.NoUnusedErrors {
+		pos := posFor(at)
+		fmt.Printf(&quot;%s: %s, but nobody cares\n&quot;, pos, check.sprintf(format, args...))
+	} else {
+		check.softErrorf(at, format, args)
+	}
+}
+
 func (check *Checker) versionErrorf(at poser, goVersion string, format string, args ...interface{}) {
 	msg := check.sprintf(format, args...)
 	if check.conf.CompilerErrorMessages {
diff --git a/src/cmd/compile/internal/types2/labels.go b/src/cmd/compile/internal/types2/labels.go
index 6f02e2fc96..d3ae602549 100644
--- a/src/cmd/compile/internal/types2/labels.go
+++ b/src/cmd/compile/internal/types2/labels.go
@@ -35,7 +35,7 @@ func (check *Checker) labels(body *syntax.BlockStmt) {
 	for name, obj := range all.elems {
 		obj = resolve(name, obj)
 		if lbl := obj.(*Label); !lbl.used {
-			check.softErrorf(lbl.pos, &quot;label %s declared but not used&quot;, lbl.name)
+			check.unusedf(lbl.pos, &quot;label %s declared but not used&quot;, lbl.name)
 		}
 	}
 }
diff --git a/src/cmd/compile/internal/types2/resolver.go b/src/cmd/compile/internal/types2/resolver.go
index 5d498b6b2b..935435b03f 100644
--- a/src/cmd/compile/internal/types2/resolver.go
+++ b/src/cmd/compile/internal/types2/resolver.go
@@ -731,15 +731,15 @@ func (check *Checker) errorUnusedPkg(obj *PkgName) {
 	}
 	if obj.name == &quot;&quot; || obj.name == &quot;.&quot; || obj.name == elem {
 		if check.conf.CompilerErrorMessages {
-			check.softErrorf(obj, &quot;imported and not used: %q&quot;, path)
+			check.unusedf(obj, &quot;imported and not used: %q&quot;, path)
 		} else {
-			check.softErrorf(obj, &quot;%q imported but not used&quot;, path)
+			check.unusedf(obj, &quot;%q imported but not used&quot;, path)
 		}
 	} else {
 		if check.conf.CompilerErrorMessages {
-			check.softErrorf(obj, &quot;imported and not used: %q as %s&quot;, path, obj.name)
+			check.unusedf(obj, &quot;imported and not used: %q as %s&quot;, path, obj.name)
 		} else {
-			check.softErrorf(obj, &quot;%q imported but not used as %s&quot;, path, obj.name)
+			check.unusedf(obj, &quot;%q imported but not used as %s&quot;, path, obj.name)
 		}
 	}
 }
diff --git a/src/cmd/compile/internal/types2/stmt.go b/src/cmd/compile/internal/types2/stmt.go
index 74d4164ba9..c4255e4413 100644
--- a/src/cmd/compile/internal/types2/stmt.go
+++ b/src/cmd/compile/internal/types2/stmt.go
@@ -66,7 +66,7 @@ func (check *Checker) usage(scope *Scope) {
 		return unused[i].pos.Cmp(unused[j].pos) &lt; 0
 	})
 	for _, v := range unused {
-		check.softErrorf(v.pos, &quot;%s declared but not used&quot;, v.name)
+		check.unusedf(v.pos, &quot;%s declared but not used&quot;, v.name)
 	}
 
 	for _, scope := range scope.children {
@@ -804,7 +804,7 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
 			v.used = true // avoid usage error when checking entire function
 		}
 		if !used {
-			check.softErrorf(lhs, &quot;%s declared but not used&quot;, lhs.Value)
+			check.unusedf(lhs, &quot;%s declared but not used&quot;, lhs.Value)
 		}
 	}
 }
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index a3c1fecb91..1f4c5c7b5c 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -179,6 +179,8 @@
 //		directory, but it is not accessed. When -modfile is specified, an
 //		alternate go.sum file is also used: its path is derived from the
 //		-modfile flag by trimming the &quot;.mod&quot; extension and appending &quot;.sum&quot;.
+//	-nounusederrors
+//		do not error on unused functions, imports, variables, etc.
 //	-overlay file
 //		read a JSON config file that provides an overlay for build operations.
 //		The file is a JSON struct with a single field, named &#39;Replace&#39;, that
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index 5f11cdabaf..b37f1c8a01 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -135,6 +135,8 @@ and test commands:
 		directory, but it is not accessed. When -modfile is specified, an
 		alternate go.sum file is also used: its path is derived from the
 		-modfile flag by trimming the &quot;.mod&quot; extension and appending &quot;.sum&quot;.
+	-nounusederrors
+		do not error on unused functions, imports, variables, etc.
 	-overlay file
 		read a JSON config file that provides an overlay for build operations.
 		The file is a JSON struct with a single field, named &#39;Replace&#39;, that
diff --git a/src/go/types/gotype.go b/src/go/types/gotype.go
index e8ff9658da..5a60b83346 100644
--- a/src/go/types/gotype.go
+++ b/src/go/types/gotype.go
@@ -47,6 +47,8 @@ The flags are:
 		verbose mode
 	-c
 		compiler used for installed packages (gc, gccgo, or source); default: source
+	-nounusederrors
+		treat &quot;unused&quot; errors as warnings
 
 Flags controlling additional output:
 
@@ -104,6 +106,7 @@ var (
 	allErrors  = flag.Bool(&quot;e&quot;, false, &quot;report all errors, not just the first 10&quot;)
 	verbose    = flag.Bool(&quot;v&quot;, false, &quot;verbose mode&quot;)
 	compiler   = flag.String(&quot;c&quot;, &quot;source&quot;, &quot;compiler used for installed packages (gc, gccgo, or source)&quot;)
+	nounusederr= flag.Bool(&quot;nounusederrors&quot;, false, &quot;treat unused objects as warnings&quot;)
 
 	// additional output control
 	printAST      = flag.Bool(&quot;ast&quot;, false, &quot;print AST&quot;)
-- 
2.38.2


Disclaimer: this isn't a comprehensive patch -- it only affects running go build or the compile tool. Should still have errors when using ast (tree parser), tracing and a few others tools because I didn't mess with internal/types, only cmd/compile/internal/types2 -- the Golang sources are a bit messy like that. I'm hoping they can refactor at some point and get rid of these redundancies.

答案10

得分: 0

你可以将其定义为包级别,虽然会有警告,但可以编译通过。

package main
import "fmt"

var i, x int = 1, 2

func main() {
  fmt.Println("Hello")
}

Go playground

如何避免烦人的错误提示“声明但未使用”?

英文:

You can define as package level, still gives warning but can compile without error.

package main
import &quot;fmt&quot;
var i, x int = 1, 2
func main() {
fmt.Println(&quot;Hello&quot;)
}

Go playground

如何避免烦人的错误提示“声明但未使用”?

答案11

得分: -1

我刚刚制作了一个新的Golang编译器,默认情况下会忽略所有的“未使用变量警告”和“未使用导入警告”。

https://github.com/yingshaoxo/go/releases/tag/v1.21

它适用于go rungo build命令。

英文:

I just made a new Golang compiler, which will simply ignore all variable unused warning and import unused warning by default.

https://github.com/yingshaoxo/go/releases/tag/v1.21

It works for both go run and go build

huangapple
  • 本文由 发表于 2014年2月13日 10:09:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/21743841.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定