当我从这个项目中休息时,出现了一个奇怪的问题。启动 Goland 后,我在尝试运行我的项目时遇到了很多错误。
构建我的一个包时的具体错误是:
start.go: package project/game is not in GOROOT (C:\Go\src\project\game)
我在下面有一个文件夹结构 C:\Users\username
go
|-src
|-project
|-game
|-entity
|-whatever.go
|-game_stuff.go
|-server
Run Code Online (Sandbox Code Playgroud)
我的环境变量是这样的:
GOROOT=C:\Go
GOPATH=C:\Users\ketchup\go
Run Code Online (Sandbox Code Playgroud)
对于每个模块(项目/游戏/实体、项目/游戏、项目/服务器),我做了一个git mod init.
在构建时,Goland 将尝试运行:
C:\Go\bin\go.exe build -o C:\Users\ketchup\AppData\Local\Temp\___go_build_project_server.exe project/server
Run Code Online (Sandbox Code Playgroud)
并返回错误。
谁能帮我解决这个问题?有点迷失,因为我上次打开 Goland 时运行良好。甚至不确定要看什么方向 - 我对 Go 还很陌生,我不确定要看什么文档:\谢谢大家!
Sau*_*abh 125
在 Go 的较新版本(1.13 后)中,您不需要设置 、 等环境GOPATH变量GOBIN。
您还需要go.mod在项目根目录中有一个文件。这将使该目录成为 Go 模块。这也是 的所在地.git/。这意味着go.mod每个存储库只需要一个。在项目根目录中你可以做go mod init remote-repo.com/username/repository
我在 macOS 上使用 Homebrew 安装了 Go,所以也是GOROOT如此/opt/homebrew/Cellar/go/1.17.5/libexec。该位置包含 Go 的标准库和运行时。
test并且run命令以格式运行go COMMAND package_path/xxx。如果不指定 package_path./并仅运行go COMMAND xxx,编译器会假设模块xxx位于 GOROOT 中,并抛出错误,package xxx is not in GOROOT (path/to/GOROOT/src/xxx)因为它不存在。
此行为是预期的,因为我们正在使用的包不是 Go SDK 的一部分,即不在GOROOT. 我们正在使用的包将最终出现在 go 工作区或当前工作目录中。运行go install编译并放入可执行二进制文件$GOBIN(又名$GOPATH/bin- 这里$GOPATH是 Go 工作区)。go build从包内部运行会编译并将可执行文件放入该目录中。
您还没有列出包内的文件server/以及哪个文件具有主要功能,因此我将模拟计算器的 3 个工作流程,每个工作流程都展示了更多的复杂性。最后一个工作流程与您的目录结构类似。
开始使用包
\n基本功能
\ncalculatorv1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.mod <- go mod init github.com/yourname/calculatorv1\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 basic/\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 add.go\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 add_test.go\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.go\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 multiply.go\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 multiply_test.go\nRun Code Online (Sandbox Code Playgroud)\n更多功能
\n多个套餐
\ncalculatorv2\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.mod <- go mod init github.com/yourname/calculatorv2\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.go\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 basic/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 add.go\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 add_test.go\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 multiply.go\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 multiply_test.go\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 advanced/\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 square.go\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 square_test.go\nRun Code Online (Sandbox Code Playgroud)\n更多功能
\n嵌套包
\ncalculatorv3\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.mod <- go mod init github.com/yourname/calculatorv3\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.go\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 basic/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 add.go\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 add_test.go\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 multiply.go\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 multiply_test.go\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80 advanced/\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 square.go\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 square_test.go\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 scientific/\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 declog.go\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 declog_test.go\nRun Code Online (Sandbox Code Playgroud)\n注意:根据您使用的版本,替换xxx为basic、advanced、 或。advanced/scientific
calculatorv1使用以下命令初始化项目目录中的 Go 模块( 、calculatorv2、 或之一calculatorv3)go mod init
运行测试
\ngo test -v ./... (从项目根目录开始,递归执行所有测试套件)
或者
\ngo test -v ./xxx (从项目根目录,运行包“xxx”中的测试套件)
或者
\ncd xxx/\ngo test -v # (from inside the package)\nRun Code Online (Sandbox Code Playgroud)\n编译并执行包
\ngo run ./... (从项目根目录,递归运行.go除测试之外的所有文件)
或者
\ngo run ./xxx (从项目根目录运行.go“xxx”包中除测试之外的所有文件)
或者
\ncd xxx\ngo run . # (from inside the package)\nRun Code Online (Sandbox Code Playgroud)\n注意:只有主包中的文件才是可执行的,即具有声明的文件package main。这意味着它go run ./xxx仅适用于版本 1,不适用于版本 2 和 3。因此,对于版本 2 和 3,请运行go run main.go
很容易填写不完整的位
\n添加去
\npackage main\n\nfunc addition(x int, y int) int {\n return x + y\n}\nRun Code Online (Sandbox Code Playgroud)\nadd_test.go
\npackage main\n\nimport "testing"\n\nfunc TestAdd(t *testing.T) {\n\n t.Run("adding two positive numbers", func(t *testing.T) {\n sum := addition(2, 2)\n expected := 4\n \n if sum != expected {\n t.Errorf("Expected %d; but got %d", expected, sum)\n }\n })\n \n t.Run("adding two negative numbers", func(t *testing.T) {\n sum := addition(-3, -4)\n expected := -7\n\n if sum != expected {\n t.Errorf("Expected %d; but got %d", expected, sum)\n }\n })\n\n t.Run("adding one positive and one negative integer", func(t *testing.T) {\n sum := addition(1, -3)\n expected := -2\n\n if sum != expected {\n t.Errorf("Expected %d; but got %d", expected, sum)\n }\n })\n \n}\nRun Code Online (Sandbox Code Playgroud)\n主程序
\npackage main\n\nimport "fmt"\n\nfunc main() {\n var num1 int = 1\n var num2 int = 2\n \n sum := addition(num1, num2)\n product := multiplication(num1, num2)\n\n fmt.Printf("The sum of %d and %d is %d\\n", num1, num2, sum)\n fmt.Printf("The multiplication of %d and %d is %d\\n", num1, num2, product)\n}\nRun Code Online (Sandbox Code Playgroud)\n主程序
\npackage main\n\nimport (\n "fmt"\n "github.com/yourname/calculatorv2/basic"\n "github.com/yourname/calculatorv2/advanced"\n)\n\nfunc main() {\n var num1 int = 1\n var num2 int = 2\n \n product := basic.Multiplication(num1, num2)\n square := advanced.Square(num2)\n\n fmt.Printf("The product of %d and %d is %d\\n", num1, num2, product)\n fmt.Printf("The square of %d is %d\\n", num2, square)\n}\nRun Code Online (Sandbox Code Playgroud)\n乘法.go
\npackage basic\n\nfunc Multiplication(x int, y int) int {\n return x * y\n}\nRun Code Online (Sandbox Code Playgroud)\n乘法测试.go
\npackage basic\n\nimport "testing"\n\nfunc TestMultiply(t *testing.T) {\n\n t.Run("multiplying two positive numbers", func(t *testing.T) {\n sum := Multiplication(2, 2)\n expected := 4\n \n if sum != expected {\n t.Errorf("Expected %d; but got %d", expected, sum)\n }\n })\n \n t.Run("multiplying two negative numbers", func(t *testing.T) {\n sum := Multiplication(-3, -4)\n expected := 12\n\n if sum != expected {\n t.Errorf("Expected %d; but got %d", expected, sum)\n }\n })\n\n t.Run("multiplying one positive and one negative integer", func(t *testing.T) {\n sum := Multiplication(1, -3)\n expected := -3\n\n if sum != expected {\n t.Errorf("Expected %d; but got %d", expected, sum)\n }\n })\n \n}\nRun Code Online (Sandbox Code Playgroud)\n广场GO
\npackage advanced\n\nfunc Square(x int) int {\n return x * x\n}\nRun Code Online (Sandbox Code Playgroud)\n主程序
\npackage main\n\nimport (\n "fmt"\n "github.com/yourname/calculatorv3/basic"\n "github.com/yourname/calculatorv3/advanced"\n "github.com/yourname/calculatorv3/advanced/scientific"\n)\n\nfunc main() {\n var num1 int = 1\n var num2 int = 2\n var num3 float64 = 2\n \n product := basic.Multiplication(num1, num2)\n square := advanced.Square(num2)\n decimallog := scientific.DecimalLog(num3)\n\n fmt.Printf("The product of %d and %d is %d\\n", num1, num2, product)\n fmt.Printf("The square of %d is %d\\n", num2, square)\n fmt.Printf("The decimal log (base 10) of %f is %f\\n", num3, decimallog)\n}\nRun Code Online (Sandbox Code Playgroud)\n广场GO
\npackage advanced\n\nfunc Square(x int) int {\n return x * x\n}\nRun Code Online (Sandbox Code Playgroud)\ndeclog.go
\npackage scientific\n\nimport "math"\n\nfunc DecimalLog(x float64) float64 {\n return math.Log10(x)\n}\nRun Code Online (Sandbox Code Playgroud)\ndeclog_test.go
\npackage scientific\n\nimport "testing"\n\nfunc TestDecimalLog(t *testing.T) {\n\n t.Run("adding two positive numbers", func(t *testing.T) {\n sum := DecimalLog(100)\n expected := 2.0\n \n if sum != expected {\n t.Errorf("Expected %f; but got %f", expected, sum)\n }\n })\n \n t.Run("adding two negative numbers", func(t *testing.T) {\n sum := DecimalLog(10)\n expected := 1.0\n\n if sum != expected {\n t.Errorf("Expected %f; but got %f", expected, sum)\n }\n })\n}\nRun Code Online (Sandbox Code Playgroud)\n
Mic*_*hum 28
一个非常愚蠢的结论(主要是我的部分),但我的问题来自go mod init在每个文件夹中都完成了。从我所做的每个文件夹中删除go.mod和删除后,我可以毫无问题地构建(通过终端)go.depgo mod init
此外,我在 GoLand 中的包没有被检测到,因为我在设置中启用了 Go 模块。我禁用了它,GoLand 能够索引外部包和我自己的包。
小智 18
您可能将 GO111MODULE 设置为“on”,这将在 go mod 中使用。关闭 GO111MODULE 可能会解决此问题。
go env -w GO111MODULE=off
Run Code Online (Sandbox Code Playgroud)
end*_*ell 11
我不喜欢每个人都给出使用 github 模块命名约定的答案,就好像你必须以这种方式命名你的模块,或者将它们放在 github 上以便在本地环境中使用,所以这是我对 \xe2\x80 的答案\x94 希望 \xe2\x80\x94 帮助澄清一些时刻,我也对 Go 中的包和模块的命名感到困惑(我将故意为文件和文件夹使用不寻常的名称,这样你就可以看到你没有以特定方式命名文件以使 Go 项目正常工作(但您必须以特定方式构建它们)):
\n因此,Golang 项目在概念上具有:
\n(对于 Go 项目来说这是可选的)
\n(这是编译 Go 项目所必需的)
\n“模块”\xe2\x80\x94 这个名称,从概念上来说,在 Go 项目中,用于指代整个程序/库(程序/库作为一个整体通常存储在某个远程存储库中)。
\n“Packages” \xe2\x80\x94 在 Go 项目中,此名称应用于存储“包文件”的文字文件夹\xe2\x80\x94 这是在模块内组织代码的一种方式。
\n实际上,上面的概念意味着如果您想创建一个多包项目,为了编译它,您需要执行以下操作:
\n(一步一步的例子:)
\n-- 创建一个文件夹作为项目的根文件夹并使用cd进入该文件夹:
\n$ mkdir some_amazing_project && cd some_amazing_project\nRun Code Online (Sandbox Code Playgroud)\n-- 当根目录下有一个有效的 go.mod 文件时,Go 代码的集合就成为一个模块,因此使用以下命令来生成它:
\n$ go mod init my_amazing_module_lib_program\nRun Code Online (Sandbox Code Playgroud)\n(go.mod 文件的内部如下所示):
\nmodule my_amazing_module_lib_program // this is your unique module identifier and you use this name as a relative root for your package names when you use "import"\n\ngo 1.19\nRun Code Online (Sandbox Code Playgroud)\n-- 现在创建一个 Go 程序的入口点,它是一个 go 文件,应放置在根文件夹(go.mod 文件所在的位置)中,但您也可以将其放置在此模块内的任何子文件夹中(根文件夹),但不能更深(否则您将收到“ no Go files in <absolute_path>/some_amazing_project/some_subfolder/another_folder ”错误):
\n$ touch some_main_file.go\nRun Code Online (Sandbox Code Playgroud)\n\n\n(^^ 你可以随意命名这个文件,但约定是“main.go”)
\n
-- 在该主文件内部,您必须指定该包为主文件,并且该文件中必须有一个也称为main 的函数:
\n// some_main_file.go\n\npackage main\n\nimport "fmt"\n\nfunc main() {\n fmt.Println("hello there")\n}\nRun Code Online (Sandbox Code Playgroud)\n(这是迄今为止您的项目结构):
\nsome_amazing_project/\n |- go.mod\n |- some_main_file.go\nRun Code Online (Sandbox Code Playgroud)\n(现在,假设您想在此模块/程序/库中创建一个包。您需要执行以下操作):
\n-- 在此模块中创建一个新文件夹,将其命名为“amazing_package”并在其中创建任何 .go 文件(文件名并不重要,因为仅包含这些文件的文件夹的名称用于引用来自其他 .go 文件的包):
\n$ mkdir amazing_package && cd amazing_package && touch whatever_file.go\nRun Code Online (Sandbox Code Playgroud)\n-- 在whatever_file.go内部,您使用package关键字来指定该包的名称(仅当指定要从其他.go 文件中调用的函数名称时,才会使用该包名称 \xe2\x80\x94稍后会看到):
\n// whatever_file.go\n\npackage wowow\n\nimport "fmt"\n\nfunc PrintWowow() {\n fmt.Println("this is from wowow package")\n}\nRun Code Online (Sandbox Code Playgroud)\n\n\n^^ 以大写字母开头的变量/常量/函数/类型/等(Go 中的任何“标识符”)将被导出,并可导入到其他包中。
\n
(为了举例,让我们在此包中创建另一个文件):
\n$ touch another_cool_file.go\nRun Code Online (Sandbox Code Playgroud)\n-- 在another_cool_file.go内部,您使用与在whatever_file.go中使用的相同的package关键字来指定该包的名称(因为这些文件在概念上位于同一个“包”中,这意味着实际上它们存储在同一文件夹中(如果将文件存储在同一文件夹中时使用不同的package关键字名称,则在编译期间将收到错误):
\n// another_cool_file.go\n\npackage wowow\n\nimport "fmt"\n\nvar Some_var = 42 // this will also be automatically exported\n\nfunc PrintAnotherWow() {\n fmt.Println("this is also from wowow package, but from a different file")\n}\nRun Code Online (Sandbox Code Playgroud)\n(这是迄今为止您的项目结构):
\nsome_amazing_project/\n |- go.mod\n |- some_main_file.go\n |- amazing_package/\n |- whatever_file.go\n |- another_cool_file.go\nRun Code Online (Sandbox Code Playgroud)\n-- 现在,要从整个模块内的任何其他 .go 文件引用“PrintWowow”和“PrintAnotherWow”函数,您可以使用go.mod文件中的唯一模块标识符以及相对于该标识符(指定包的位置)的路径要导入的文件夹(在本例中我将使用 some_main_file.go 。我们像这样重写它):
\n// some_main_file.go\n\npackage main\n\nimport (\n "fmt"\n "my_amazing_module_lib_program/amazing_package"\n)\n\nfunc main() {\n fmt.Println("hello there")\n\n // now you use the name of the package specified by the "package" keyword inside of those files from *amazing_package* folder\n wowow.PrintWowow()\n wowow.PrintAnotherWow()\n fmt.Println("and this is Some_var from the same imported package:", wowow.Some_var)\n}\nRun Code Online (Sandbox Code Playgroud)\n这是在my_amazing_module_lib_programgo build . && go run . (根)文件夹内运行的结果:
hello there\nthis is from wowow package\nthis is also from wowow package, but from a different file\nand this is Some_var from the same imported package: 42\nRun Code Online (Sandbox Code Playgroud)\n
所以看起来如果你运行 go mod init 'xxx' xxx 是你项目的核心名称。在那里主要包的完整名称是“xxx/main”,所以如果你的项目根文件夹是这样的:
root -> go mod init xxx
|- main.go -> package "main"
|- tools
|- helper.go -> package "tools"
Run Code Online (Sandbox Code Playgroud)
如果你想从 main.go 导入工具包,你需要导入这个“xxx/tools”