解决golang有未使用的变量和包时编译报错的问题
Go语言将variable declared but not used和package imported but not used设计成错误,正常使用无可厚非,但调试代码时会非常恼人。下面,就通过修改go源码将这两类错误改为警告。利益于golang的神奇编译速度,几分钟就可以轻松搞定。
首先看看效果吧:
// 测试代码
package main
import (
"time"
"fmt"
)
func main() {
var i int
fmt.Println("hello world!")
}
// 运行结果
➜ work go run main.go
# command-line-arguments
./main.go:4:2: imported and not used: "time"
./main.go:9:6: i declared and not used
hello world!
不过,对于用来上线生产的代码,还是务必把所有的警告解决掉。
golang1.9修改方式
- 解决variable declared but not used,通过修改go/src/cmd/compile/internal/gc/walk.go中的
func walk(fn *Node)
函数,其实就是把这里的Yyerror改成Warn。
➜ gc diff walk.bak walk.go
53c53
< yyerrorl(defn.Left.Pos, "%v declared and not used", ln.Sym)
---
> Warnl(defn.Left.Pos, "%v declared and not used", ln.Sym)
56c56
< yyerrorl(ln.Pos, "%v declared and not used", ln.Sym)
---
> Warnl(ln.Pos, "%v declared and not used", ln.Sym)
- 解决package imported but not used,通过修改go/src/cmd/compile/internal/gc/main.go中的
func pkgnotused(lineno src.XPos, path string, name string)
函数,也就是将这里的yyerrorl改成Warnl。
➜ gc diff main.bak main.go
1089c1089
< yyerrorl(lineno, "imported and not used: %q", path)
---
> Warnl(lineno, "imported and not used: %q", path)
1091c1091
< yyerrorl(lineno, "imported and not used: %q as %s", path, name)
---
> Warnl(lineno, "imported and not used: %q as %s", path, name)
golang1.5.1修改方法
- 解决variable declared but not used,通过修改go/src/cmd/compile/internal/gc/walk.go中的
func walk(fn *Node)
函数,其实就是把这里的Yyerror改成Warn。
for l := fn.Func.Dcl; l != nil; l = l.Next {
if l.N.Op != ONAME || l.N.Class&^PHEAP != PAUTO || l.N.Sym.Name[0] == '&' || l.N.Used {
continue
}
if defn := l.N.Name.Defn; defn != nil && defn.Op == OTYPESW {
if defn.Left.Used {
continue
}
lineno = defn.Left.Lineno
//修改此行为下面这行Yyerror("%v declared and not used", l.N.Sym)
Warn("%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)
Warn("%v declared and not used", l.N.Sym)
}
}
- 解决package imported but not used,通过修改go/src/cmd/compile/internal/gc/lex.go中的
func pkgnotused(lineno int, path string, name string)
函数,也就是将这里的yyerrorl改成Warnl。
func pkgnotused(lineno int, path string, name string) {
// ...这里省略掉注释
elem := path
if i := strings.LastIndex(elem, "/"); i >= 0 {
elem = elem[i+1:]
}
if name == "" || elem == name {
//修改此行为下面一行yyerrorl(int(lineno), "imported and not used: %q", path)
Warnl(int(lineno), "imported and not used: %q", path)
} else {
//修改此行为下面一行yyerrorl(int(lineno), "imported and not used: %q as %s", path, name)
Warnl(int(lineno), "imported and not used: %q as %s", path, name)
}
}
golang1.4及以下版本修改方式
- 解决variable declared but not used,通过修改go/src/cmd/gc/walk.c
for(l=fn->dcl; l; l=l->next) {
if(l->n->op != ONAME || (l->n->class&~PHEAP) != PAUTO || l->n->sym->name[0] == '&' || l->n->used)
continue;
if(l->n->defn && l->n->defn->op == OTYPESW) {
if(l->n->defn->left->used)
continue;
lineno = l->n->defn->left->lineno;
//修改此行为下一行 yyerror("%S declared and not used", l->n->sym);
warn("[Warning] %S declared and not used", l->n->sym);
l->n->defn->left->used = 1; // suppress repeats
} else {
lineno = l->n->lineno;
//修改此行为下一行 yyerror("%S declared and not used", l->n->sym);
warn("[Warning] %S declared and not used", l->n->sym);
}
}
- 解决package imported but not used,通过修改go/src/cmd/gc/lex.c
for(h=0; h<NHASH; h++) {
for(s = hash[h]; s != S; s = s->link) {
if(s->def == N || s->pkg != localpkg)
continue;
if(s->def->op == OPACK) {
// throw away top-level package name leftover
// from previous file.
// leave s->block set to cause redeclaration
// errors if a conflicting top-level name is
// introduced by a different file.
if(!s->def->used && !nsyntaxerrors) {
//修改此行为下面两行 pkgnotused(s->def->lineno, s->def->pkg->path, s->name);
lineno = s->def->lineno;
warn("[Warning] imported and not used: \"%Z\"" , s->def->pkg->path);
}
s->def = N;
continue;
}
golang编译方法
修改完后,cd到go/src下运行sudo ./make.bash,稍等,搞定!
golang1.4以上的版本的编译需要另一个golang1.4或更高版本的来编译,一个简单的方法是下载一份golang1.4(或更高)的二进制版本,解压出两份来,如分别命名gomy,go15,按上面的方法修改gomy里面的代码后,设置好GOROOT_BOOTSTRAP环境变量为go15这个目录的绝对路径,cd到gomy/src下运行./make.bash,稍等,搞定!之后就可以把gomy放到你喜欢的位置,设置好GOROOT,GOPATH等环境亦是就可以使用了。
作者原创,转载请注明出处
有疑问加站长微信联系(非本文作者)