在开发代码过程中,经常会因为逻辑处理而对代码进行分类,放进不同的文件里面;像这样,同一个包下的两个文件,点击idea的运行按钮或者运行 go run main.go命令时,就会报错,如图所示。
一 问题是在我写算法题的时候出的,test后缀的文件编译报command-line-arguments undefined: xxxxx ?
} func main() { stu := new(Student) stu.Name = "tom" } 分析结果: go run -gcflags '-m -l' 01.go # command-line-arguments } func main() { stu := new(Student) stu.Name = "tom" } 分析结果: go run -gcflags '-m -l' 01.go # command-line-arguments stu.Name = "tom" return stu } func main() { GetStudent() } 分析结果: go run -gcflags '-m -l' 02.go # command-line-arguments int, 10000, 10000) for i := range nums { nums[i] = i } } 分析结果: go run -gcflags '-m -l' 03.go # command-line-arguments
" ) func main() { s := "hello" fmt.Println(s) } go run -gcflags '-m -l' escape.go Output: # command-line-arguments { var x S y := &x _ = *identity(y) } func identity(z *S) *S { return z } Output: # command-line-arguments S struct{} func main() { var x S _ = *ref(x) } func ref(z S) *S { return &z } Output: # command-line-arguments var i int refStruct(&i) } func refStruct(y *int) (z S) { z.M = y return z } Output: # command-line-arguments ) { var x S var i int ref(&i, &x) } func ref(y *int, z *S) { z.M = y } Output: # command-line-arguments
" ) func main() { s := "hello" fmt.Println(s) } go run -gcflags '-m -l' escape.go Output: # command-line-arguments { var x S y := &x _ = *identity(y) } func identity(z *S) *S { return z } Output: # command-line-arguments S struct{} func main() { var x S _ = *ref(x) } func ref(z S) *S { return &z } Output: # command-line-arguments var i int refStruct(&i) } func refStruct(y *int) (z S) { z.M = y return z } Output: # command-line-arguments ) { var x S var i int ref(&i, &x) } func ref(y *int, z *S) { z.M = y } Output: # command-line-arguments
参考文章解决Go test执行单个测试文件提示未定义问题 执行vm_test.go cd github.com\ethereum\go-ethereum\tests go test vm_test.go # command-line-arguments \vm_test.go:32:3: undefined: withTrace FAIL command-line-arguments [build failed] 如果一个个添加发现非常麻烦,找到简单的方法
:= &x _ = *identity(y) } func identity(z *S) *S { return z } go run -gcflags '-m -l' main.go # command-line-arguments identity(y) fmt.Println(c) } func identity(z *S) *S { return z } go run -gcflags '-m -l' main.go # command-line-arguments main() { var x S _ = *ref(x) } func ref(z S) *S { return &z } go run -gcflags '-m -l' main.go # command-line-arguments interface类型逃逸 package main import "fmt" func main() { str := "str" fmt.Printf("%p", &str) } # command-line-arguments go run -gcflags '-m -m -l' main.go # command-line-arguments ./main.go:7:14: a escapes to heap: .
不会主动执行benchmark函数的,需要增建 -test_bench,所以下面的代码不会执行任何压力测试 go test bench_test.go ok command-line-arguments 6.17 ns/op BenchmarkStr-8 2000000000 0.34 ns/op PASS ok command-line-arguments goos: linux goarch: amd64 BenchmarkStr-8 2000000000 0.34 ns/op PASS ok command-line-arguments : invoking "go tool vet" directly is unsupported; use "go vet" 下面执行结果表示当前代码行无法被执行的 go vet main.go # command-line-arguments go vet main.go # command-line-arguments .
m" escape.go //详情 go build -gcflags "-m -m" escape.go 对于例1.3中的代码,执行go build -gcflags "-m",得到结果如下: # command-line-arguments int { a, b = b, a+b return a } } 查看逃逸情况如下: go build -gcflags "-m -l" escape.go # command-line-arguments 对应的内存可能在外部被使用,放到堆上 return &u } func main() { } 查看逃逸情况如下: go build -gcflags "-m -l" escape.go # command-line-arguments make([]int32, n) s[0] = 1 } func main() { } 查看逃逸情况如下 go build -gcflags "-m -m -l" escape.go # command-line-arguments 我能说什么呢… go build -gcflags "-m -l" escape.go # command-line-arguments .
来分析分析: YDZ ~/LeetCode_Go/helloworld/src/me $ go run -n helloworld.go # # command-line-arguments # mkdir -p $WORK/command-line-arguments/_obj/ mkdir -p $WORK/command-line-arguments/_obj/exe/ cd /Users command-line-arguments 这个归档文件是 Go 语言为命令源码文件临时指定的一个代码包。在接下来的几个命令中,生成的临时代码包都叫这个名字。 # # command-line-arguments # mkdir -p $WORK/command-line-arguments/_obj/ mkdir -p $WORK/command-line-arguments # # command-line-arguments # mkdir -p $WORK/command-line-arguments/_obj/ mkdir -p $WORK/command-line-arguments
" ) func main() { s := "hello" fmt.Println(s) } go run -gcflags '-m -l' escape.go Output: # command-line-arguments { var x S y := &x _ = *identity(y) } func identity(z *S) *S { return z } Output: # command-line-arguments S struct{} func main() { var x S _ = *ref(x) } func ref(z S) *S { return &z } Output: # command-line-arguments var i int refStruct(i) } func refStruct(y int) (z S) { z.M = &y return z } Output: # command-line-arguments var i int refStruct(&i) } func refStruct(y *int) (z S) { z.M = y return z } Output: # command-line-arguments
(因为go是动态栈不安全) $ go build -gcflags "-m" main.go # command-line-arguments /var/folders/r9/35q9g3d56_ d9g0v59w9x2l9w0000gn/T/go-build789689150/command-line-arguments/_obj/_cgo_gotypes.go:14:6: can inline _Cgo_ptr /var/folders/r9/35q9g3d56_d9g0v59w9x2l9w0000gn/T/go-build789689150/command-line-arguments/_ param: ptr to result ~r1 level=0 /var/folders/r9/35q9g3d56_d9g0v59w9x2l9w0000gn/T/go-build789689150/command-line-arguments assuming arg#2 is unsafe uintptr /var/folders/r9/35q9g3d56_d9g0v59w9x2l9w0000gn/T/go-build789689150/command-line-arguments
对如下编译错误: go build -o hello main.go build command-line-arguments: cannot load google.golang.org/grpc 128 2 21 14:11 google.golang.org 如遇到如下错误: go: downloading google.golang.org/grpc v1.27.1 build command-line-arguments
-v" hello.go WORK=/var/folders/v8/xdj2snz51sg2m2bnpmwl_91c0000gn/T/go-build149644699 mkdir -p $WORK/command-line-arguments Cellar/go/1.4.2/libexec/pkg/tool/darwin_amd64/6g -o $WORK/command-line-arguments.a -trimpath $WORK -p command-line-arguments -o hello -L $WORK -X main.hi hi -linkmode=external -v -extld=clang $WORK/command-line-arguments.a # command-line-arguments
132 ns/op BenchmarkDirect_Set-4 30000000 53.0 ns/op PASS ok command-line-arguments 最后一行 command-line-arguments 10.982s,代表总的执行时间为 10.982s。 windows goarch: amd64 BenchmarkReflect_New-4 20000000 84.9 ns/op PASS ok command-line-arguments BenchmarkDirect_Set-4 30000000 52.4 ns/op 48 B/op 1 allocs/op PASS ok command-line-arguments
来分析分析: YDZ ~/LeetCode_Go/helloworld/src/me $ go run -n helloworld.go # # command-line-arguments # mkdir -p $WORK/command-line-arguments/_obj/ mkdir -p $WORK/command-line-arguments/_obj/exe/ cd /Users command-line-arguments 这个归档文件是 Go 语言为命令源码文件临时指定的一个代码包。在接下来的几个命令中,生成的临时代码包都叫这个名字。 # # command-line-arguments # mkdir -p $WORK/command-line-arguments/_obj/ mkdir -p $WORK/command-line-arguments # # command-line-arguments # mkdir -p $WORK/command-line-arguments/_obj/ mkdir -p $WORK/command-line-arguments
PASS: TestSub (0.00s) --- PASS: TestSub/A=1 (0.00s) --- PASS: TestSub/A=2 (0.00s) PASS ok command-line-arguments TestSub === RUN TestSub/A=1 --- PASS: TestSub (0.00s) --- PASS: TestSub/A=1 (0.00s) PASS ok command-line-arguments TestSubParallel/group/Test2 (1.01s) --- PASS: TestSubParallel/group/Test1 (2.00s) PASS ok command-line-arguments unit_test.go -v TestMain setup. === RUN TestAdd --- PASS: TestAdd (0.00s) PASS TestMain tear-down. ok command-line-arguments
0.102s 4%: 0.005+0.51+0.049 ms clock, 0.022+0.10/0.40/0.93+0.19 ms cpu, 4->4->1 MB, 5 MB goal, 4 P # command-line-arguments @0.005s 9%: 0.008+3.3+0.071 ms clock, 0.035+0.18/3.0/2.4+0.28 ms cpu, 4->5->3 MB, 5 MB goal, 4 P # command-line-arguments
0.00s) === CONT TestA --- PASS: TestA (0.00s) === CONT TestB --- PASS: TestB (0.00s) PASS ok command-line-arguments TestB === CONT TestA --- PASS: TestA (0.00s) === CONT TestB --- PASS: TestB (0.00s) PASS ok command-line-arguments TestB === CONT TestA --- PASS: TestA (0.00s) === CONT TestB --- PASS: TestB (0.00s) PASS ok command-line-arguments
func main() { p := foo(666) println(*p, p) } 查看逃逸分析日志: $ go build -gcflags=-m 1_example.go # command-line-arguments func main() { p := fooss(666) println(*p, p) } 查看逃逸分析日志: $ go build -gcflags=-m 1_new_example.go # command-line-arguments for index, _ := range s { s[index] = index } } $ go build -gcflags=-m 3_make1000_example.go # command-line-arguments for index, _ := range s { s[index] = index } } $ go build -gcflags=-m 3_make10000_example.go # command-line-arguments