如何禁用Golang未使用的导入错误


96

默认情况下,Go将未使用的导入视为错误,从而迫使您删除导入。我想知道是否有某种希望改变这种行为,例如将其减少为警告。

我发现这个问题非常烦人,使我无法使用Go编码。

例如,我正在测试一些代码,禁用段/功能。库中的某些功能不再使用(例如,fmt,错误等),但是经过一些测试后,我将需要重新启用该功能。现在,除非删除这些导入,否则程序将无法编译,几分钟后,我需要重新导入该库。

在开发GAE程序时,我一次又一次地执行此过程。


1
在代码中保留未使用的导入不是一个好主意,但是您可以暂时将它们注释掉。
elithrar

70
我同意保留未使用的导入不是一个好主意,但是不必要地浪费程序员的精力去做这样的事情是一个坏主意,尤其是在测试某些东西时,这种情况经常发生。那些不赞成投票的人一定是我对那些围棋粉丝的态度。
尼克,

6
这是一个功能,而不是错误
Beatgammit

1
删除未使用的导入是一件好事。有许多样式指南要求将所有警告均视为错误,因此添加新警告通常是一个坏主意。也许-dev标志可能是一个折衷方案,但var _ = <module>.Function工作正常,而且足够明显,可以防止它成为常见的做法。
deft_code

1
当有人在下面的答案中提及时,我建议您使用管理导入的IDE(Gogland,LiteIDE等-有多个),或者建议goimports您进行构建。没有任何一个,它很快就会变老。
约瑟夫·

Answers:


36

_在软件包名称之前添加下划线()将忽略未使用的导入错误。

以下是如何使用它的示例:

import (
    "log"
    "database/sql"

    _ "github.com/go-sql-driver/mysql"
)

要仅出于副作用(初始化)导入软件包,请使用空白标识符作为显式软件包名称。

https://golang.org/ref/spec#Import_declarations查看更多


这是正确的答案。基于GoLang规范Doc,它旨在用于仅出于副作用(初始化)的目的导入软件包。GoLang规格文件的位置:golang.org/ref/spec#Import_declarations
威尔

简直太棒了。这应该列在golang新手开发人员应该知道的十大事项中。谢谢!
JM Janzen '02

9
不是很有用。这样做的问题是,如果您以后要再次使用导入,则必须将其删除_(否则将无法引用该软件包,因为它没有名称)。如果您打算这样做,则最好对其进行注释/取消注释。该var _ = ...招不存在这个问题。
EM0

如果"fmt"在Gogland 中将下划线添加到,则会自动添加下划线,"fmt"以便您同时具有_"fmt""fmt",这在此IDE
中将其变为

26

这个var _ = fmt.Printf技巧在这里很有帮助。


我喜欢这个解决方案。丑陋到足以使它不受欢迎,但是它可以工作,因此如果您真的需要它,它就可以使用。
deft_code

3
有关更多详细信息,请检查此链接tip.golang.org/doc/effective_go.html#blank_unused
Deepak Singh Rawat

3
目前它很有用,但是当我使用这种技术时,我倾向于以后不回去删除未使用的空白标识符,当我真的不打算长期使用它们时,会导致导入卡住。使用goimports之类的工具已经解决了实际问题,并确保我的导入始终最小且干净。
mdwhatcott 2015年

在我看来,这仍然是一个愚蠢的黑客,尽管这可能是最有效的方法。
安东尼

+1是因为它可以在文件中的任何地方完成,这通常是一个糟糕的主意,但对于节省import您在尝试编译或测试时不必在文件中跳转来获取该语句并返回该字段的真正有用之处您正在反复充实的一些代码文件。
mtraceur

21

我也有同样的问题。我了解他们实施该语言以禁止未使用的导入和变量的原因,但是我个人认为编写此代码时此功能很烦人。为了解决这个问题,我更改了编译器,以允许使用可选标志来允许未使用的变量和代码导入。

如果您有兴趣,可以在https://github.com/dtnewman/modified_golang_compiler上看到。

现在,我可以简单地使用诸如go run -gcflags'-unused_pkgs'test.go之类的命令运行代码,并且不会引发这些“未使用的导入”错误。如果我忽略了这些标志,那么它将返回默认值,即不允许未使用的导入。

只需进行一些简单的更改即可。Go纯粹主义者可能不会对这些更改感到满意,因为有充分的理由不允许未使用的变量/导入,但是我个人同意您的意见,这个问题使得在Go中编写代码变得不那么愉快了,这就是我对我进行这些更改的原因编译器。


2
我对1.6版本也做了同样的操作,如果有兴趣,请在这里检查:github.com/ronelliott/go/tree/release-branch.go1.6注意:某些测试将失败
Ron E

2
我喜欢这个背后的想法。我看到您的fork仍然是1.2版,这使它毫无用处。这至少应包括在标准的go编译器中,以便至少go run main.go在默认情况下禁用错误,而在go build启用错误的同时。这样一来,使用起来就很容易开发,go run并且当需要为生产而构建时,您仍然被迫清理代码。
kramer65

17

使用goimports。它基本上是gofmtBrad Fitzpatrick编写的,现在包含在go工具包中。您可以将编辑器配置为在保存文件时运行它。您再也不必担心这个问题。


5

如果fmt在开发和测试时使用软件包进行常规打印以进行控制台,则可以在日志软件包中找到更好的解决方案。


5
还是println人们总是会忘记的内置函数。
MatrixFrog

2
@MatrixFrog从长远来看,建立这些功能不是一个好主意,因为它们会随着时间而消失。使用日志是一个好主意,因为您可以保留这些日志,它是标准库的一部分,不太可能被删除。有关详细信息,请参见规格
nemo 2013年

1
内置println?? 这对我来说是新闻。它没有证件吗?我在任何地方都找不到。
马特

1
@nemo好点。当您需要一次打印一次但又不想真正将其打印出来时,它们是理想的选择。在任何其他情况下使用它们可能都不好。
MatrixFrog

1
@MartinTournoij-我不同意。这是我5年前遇到这个问题时最终找到的解决方案,并且经过5次以上的投票,显然对其他人有所帮助。我是一个使用该fmt程序包进行日志记录的新手,没有意识到有一个现成的日志记录程序包。
OldCurmudgeon

5

使用if false { ... }注释掉一些代码。花括号内的代码在语法上必须正确,但否则可以是废话代码。


3
除语法上正确外,任何引用的变量(例如foo.Bar)都必须存在,等等。–
Dragon

这不是很干净或惯用的。Go的设计原由是有原因的
Acidic9

1
当人们只是在Golang中开发脚本或探索API时尝试一些事情时,这是一种不错的技术。谢谢topskip!
杰伊·泰勒

2

许多人已经发表了有根据的论据,我也承认原作者的意图。但是,Rob Pike在不同的论坛中提到,Go是简化其他少数主流编程语言所缺少或不容易实现的过程的结果。Go的语言语义以及使编译更快的速度,采用了许多最初看起来效率低下的东西。

简而言之,未使用的导入被认为是Go中的错误,因为它会弄脏程序并减慢编译速度。使用副作用(_)导入是一种解决方法,但是,当混合了有效导入和副作用以及纯粹出于调试/测试目的而导入的副作用时,尤其是在代码库为很大,有机会忘记而不是无意删除,这以后可能会使其他工程师/审阅者感到困惑。我曾经将未使用的注释掉,但是,流行的IDE(例如VS代码和Goland)可以goimports轻松使用,从而可以很好地插入和删除导入。请参阅链接以获取更多信息,https://golang.org/doc/effective_go.html#blank_import


谢谢你!我建议明确地从您张贴到响应中的URL复制代码行,作为导入副作用的具体示例: import _ "net/http/pprof"
Dragon

1
感谢@Dragon的建议!由于我是新的撰稿人,因此在像您这样的人的帮助下,我的帖子会很快变得更好。
sbcharr

-1

将其放在文档顶部,然后忽略未使用的导入:

import (
    "bufio"
    "fmt"
    "os"
    "path/filepath"
)

var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs

1
如果您确实想这样做,不必使编译器生成无效代码,而应使用_全局变量(例如,每行一个包,或者如果您坚持,则将所有变量都像这样:)var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs。但是不要这样做,只需使用即可goimports
Dave C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.