执行go run出现.\main.go:6:10: undefined: Test

复现问题

首先来看问题是怎么出现的。在gotest目录下,有testundefined.gomain.go文件。其中main.go文件引用了testundefined.go中的结构体Test。编写没有语法错误,但是在运行go run命令时,却报错:

# command-line-arguments
.\main.go:6:10: undefined: Test

testundefined.go文件:

package main

type Test struct {
	Name string
	Year int
}

main.go文件:

package main

import "fmt"

func main() {
	test := Test{
		"benben",
		2015,
	}
	fmt.Println(test)
}

原因查找

既然是在运行go run命令的时候出错,那么首先来看执行命令的入口。位于$GOPATH/src/cmd/go目录下的main.go文件,是命令运行的入口。该文件导入了cmd/go/internal/run包,那么势必要运行该包下的初始化函数。

func init() {
    CmdRun.Run  = runRun // break init loop

    work.AddBuildFlags(CmdRun)
    CmdRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
}

初始化函数第一行是运行run命令的函数:
执行go run出现.\main.go:6:10: undefined: Test_第1张图片
首先它会搭建运行环境,然后检测文件是否合乎规则(是否是.go文件,是否是_test.go文件等)。如果检测通过,它会创建一个用于构建Go文件集合的包(GoFilesPackage接口实现)。
执行go run出现.\main.go:6:10: undefined: Test_第2张图片
接着将创建的集合加入导入栈(ImportStack []string)中进行加载,加载完成后从栈中取出。

    ...
    stk.Push("main")
    pkg.load(&stk, bp, err)
    stk.Pop()
    ...

由于启动的时候只传入了一个参数main.go,而依赖的文件testundefined.go没有被导入。这样main函数在运行时就找不到testundefined.go文件中的Test结构体。

解决方法

当同一个包下,文件存在依赖关系时,应该把依赖的文件都传入加载参数里面。例如:

D:\gotest>go run main.go testundefined.go
{benben 2015}

你可能感兴趣的:(GO学习总结)