我遇到了go run main.go
产生错误的问题:
# command-line-arguments
./main.go:9: undefined: test
但是命令go build && ./goruntest
编译并运行程序就好了。
输出结果为:
你好,来自test()
你好,来自sameFileTest()
您好,来自pkgtest.Test()
您好,来自pkgtest.Test1()
我的目录设置如下:
go/src/github.com/username/goruntest/
pkgtest/
pkgtest.go
pkgtest1.go
main.go
test2.go
这是代码。
main.go
package main
import (
"fmt"
"github.com/username/goruntest/pkgtest"
)
func main() {
fmt.Println(test()) // main.go:9
fmt.Println(sameFileTest())
fmt.Println(pkgtest.Test())
fmt.Println(pkgtest.Test1())
}
func sameFileTest() string {
return "Hi from sameFileTest()"
}
gotest1.go
package main
func test() string {
return "Hi from test()"
}
pkgtest / pkgtest.go
package pkgtest
func Test() string {
return "Hi from pkgtest.Test()"
}
pkgtest / pkgtest1.go
package pkgtest
func Test1() string {
return "Hi from pkgtest.Test1()"
}
我理解问题是第二个文件是package main
的一部分,我也理解没有真正的理由在main
中有第二个文件。
我的问题是:为什么go run
无法处理此设置,但构建和运行可执行文件的工作正常?
修改
在pkgtest
我也理解命令go run main.go gotest1.go
有效,但为什么我需要指定gotest1.go
?
为了简洁起见,我最初省略了这些细节。但现在我发现他们对这个问题很重要。
答案 0 :(得分:6)
尝试将所有相关文件提供给go run
$ go help run
usage: go run [build flags] [-exec xprog] gofiles... [arguments...]
Run compiles and runs the main package comprising the named Go source files.
A Go source file is defined to be a file ending in a literal ".go" suffix.
答案 1 :(得分:0)
我想在这里分享一些有用的资源以供参考,这是我从另一个类似的已删除帖子中学到的。它看起来像一个简单的命令,但你可能并不完全了解它。
go run
提供源文件列表,则您正在创建单个综合包,并且会忽略构建约束。因此,与其列出 go 文件,不如使用导入路径或文件系统路径,例如go run .
。用go help packages
检查一下:As a special case, if the package list is a list of .go files from a
single directory, the command is applied to a single synthesized
package made up of exactly those files, ignoring any build constraints
in those files and ignoring any other files in the directory.
// GoFilesPackage creates a package for building a collection of Go files
// (typically named on the command line). The target is named p.a for
// package p or named after the first Go file for package main.
func GoFilesPackage(ctx context.Context, gofiles []string) *Package {
...
The declaration order of variables declared in multiple files is determined by the order in which the files are presented to the compiler: Variables declared in the first file are declared before any of the variables declared in the second file, and so on.
...
A package with no imports is initialized by assigning initial values to all its package-level variables followed by calling all init functions in the order they appear in the source, possibly in multiple files, as presented to the compiler.
...
To ensure reproducible initialization behavior, build systems are encouraged to present multiple files belonging to the same package in lexical file name order to a compiler.