修改go编译器允许代码存在未使用的变量和包

修改go编译器允许代码存在未使用的变量和包

先直接看修改之后的结果,这样一份代码

package main

import "fmt"
import "log"

func main() {
    a := 1
    log.Println("aaaaa")
}

编译结果如下:

➜  test  go run w.go
# command-line-arguments
./w.go:3: imported and not used2: "fmt"
./w.go:7: a declared and not used2
2015/09/21 17:36:34 aaaaa

可以看到,虽然提示了代码的问题,但是还是编译并运行成功了。

接下来就告诉大家如何修改。
首先确认你的golang版本和我的一样,

➜  test  go version
go version go1.5.1 darwin/amd64

然后进入$GOROOT目录(golang安装目录), 按照下面的diff修改即可。

diff --git a/src/cmd/compile/internal/gc/lex.go b/src/cmd/compile/internal/gc/lex.go
index 606298b..ef9b59a 100644
--- a/src/cmd/compile/internal/gc/lex.go
+++ b/src/cmd/compile/internal/gc/lex.go
@@ -2584,9 +2584,9 @@ func pkgnotused(lineno int, path string, name string) {
                elem = elem[i+1:]
        }
        if name == "" || elem == name {
-               yyerrorl(int(lineno), "imported and not used: %q", path)
+               adderr(int(lineno), "imported and not used2: %q", path)
        } else {
-               yyerrorl(int(lineno), "imported and not used: %q as %s", path, name)
+               adderr(int(lineno), "imported and not used3: %q as %s", path, name)
        }
 }

diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index 866d8e1..56d3875 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -348,7 +348,7 @@ func importdot(opkg *Pkg, pack *Node) {

        if n == 0 {
                // can't possibly be used - there were no symbols
-               yyerrorl(int(pack.Lineno), "imported and not used: %q", opkg.Path)
+               adderr(int(pack.Lineno), "imported and not used1: %q", opkg.Path)
        }
 }

diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index af3e1cc..f9c35b0 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -51,11 +51,11 @@ func walk(fn *Node) {
                                continue
                        }
                        lineno = defn.Left.Lineno
-                       Yyerror("%v declared and not used", l.N.Sym)
+                       adderr(parserline(), "%v declared and not used", l.N.Sym)
                        defn.Left.Used = true // suppress repeats
                } else {
                        lineno = l.N.Lineno
-                       Yyerror("%v declared and not used", l.N.Sym)
+                       adderr(parserline(), "%v declared and not used2", l.N.Sym)
                }
        }

(END)

然后

➜  test  go build -x cmd/compile
WORK=/var/folders/5x/bg9pbd6x5dv70kt_mq5ys16w0000gn/T/go-build774122134
mkdir -p $WORK/cmd/internal/gcprog/_obj/
mkdir -p $WORK/cmd/internal/
cd /usr/local/go/src/cmd/internal/gcprog
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/cmd/internal/gcprog.a -trimpath $WORK -p cmd/internal/gcprog -complete -buildid f02cd5f66694d70425b46f6ebd53b46222f5086a -D _/usr/local/go/src/cmd/internal/gcprog -I $WORK -pack ./gcprog.go
mkdir -p $WORK/cmd/compile/internal/big/_obj/
mkdir -p $WORK/cmd/compile/internal/
cd /usr/local/go/src/cmd/compile/internal/big
......

这样会在当前目录生成compile。然后上面输出可以找到 /usr/local/go/pkg/tool/darwin_amd64/compile这个二进制文件,
用当前目录生成的compile覆盖之前的就ok了。

文章地址 https://github.com/wangkechun/golang-learn/blob/master/article/go-compile-allowed-unused-packages-and-vars.md

共 10 个回复


ylqjgm

感觉没有必要啊,Golang设计之初就是为了规范化,如果非要把这个规范化的东西修改没了,那代码不是又凌乱了?

而且,既然是没有使用的包和变量,为何还要保留呢?

当然,楼主的研究值得肯定的!

# 0

stevewang

这是倒洗澡水,结果把孩子倒了又加了点脏水

# 1

bigwhite

估计楼主就是玩玩吧。

# 3

Rumia

加个参数 如果有个参数就严格检查 否则 不严格检查 开发的时候就不必那么痛苦的去注释了

# 4

CodyGuo

没必要,导入库多了,第一:编译时间长,第二程序包大。
还不如花时间去注释一下没用的导入包。

不过楼主技术果然牛,这都能解决,求多点其他技术分享。

# 5

stevewang

@Rumia
如果允许用参数忽略编译错误,结果就是和直接忽略错误一样。

# 6

vincentccnt

赞!
这种强制限制会让开发过程非常痛苦,居然没有开关可以关掉,足见galang设计者具有十足的偏见和傲慢

# 7

iPixelOldC

我就想知道不允许未使用过的变量或者包存在,这和GO设计者有十足的傲慢和偏见有什么关系?就事论事,人家这么设计也有别人的道理啊,你总不能因为这种模式让自己的开发变得麻烦就说设计者咋样咋样吧,所以上面的那位不喜欢这种设计就别用go啊。。。并且现在很多IDE或者编辑器注释东西不就是一个快捷键的事吗?有那么复杂?(你要是用notepad这种当我没说)。。。其次这种设计在我这种菜鸟看来不就是强制要求你先想清楚再写吗。。。所以自己不喜欢go就别用,免得哪天go把你坑了,然后就开始各种黑go说go的坏话,这样对大家都不好。。。我没有喷你啊,没这个意思,别误解啊

# 8

iPixelOldC

其次。。。你要是说没有开关可以关掉,体现了设计者缺乏人性化的考虑,没有考虑到我们这种不可能一次就写完美的菜鸟的感受,我也觉得确实很对。。。但是体现其十足的傲慢和偏见。。。这真的看不出来啊

# 9