I have a weird issue that arose when I took a break from this project. Upon starting up Golang, I'm riddled with errors when trying to run my project.
The specific error, when building one of my packages, is: start.go: package project/game is not in GOROOT (C:\Go\src\project\game)
I have a folder structure as such under C:\Users\username
go
|-src
|-project
|-game
|-entity
|-whatever.go
|-game_stuff.go
|-server
and my env vars are as such:
GOROOT=C:\Go
GOPATH=C:\Users\ketchup\go
for each of the modules (project/game/entity, project/game, project/server), I did a git mod init
.
When building, Goland will try to run this:
C:\Go\bin\go.exe build -o C:\Users\ketchup\AppData\Local\Temp\___go_build_project_server.exe project/server
and return the error.
Can anyone help me with this issue? Kind of lost since Goland was working fine the last time I opened it. Also not even sure what direction to look at - I'm pretty new to Go and I'm not really sure what documentation to look at :\ Thank you everyone!
ベストアンサー1
In newer versions (post 1.13) of Go, you don't need to set environment variables like GOPATH
, GOBIN
, etc.
You also need to have a go.mod
file at the project root. This will make the directory a Go module. This is also where the .git/
is located. This means that only one go.mod
is needed per repository. Inside the project root you could do a go mod init remote-repo.com/username/repository
I installed Go using Homebrew on macOS so GOROOT
is /opt/homebrew/Cellar/go/1.17.5/libexec
. This location contains the standard library and runtimes for Go.
test
and run
commands are run in the format go COMMAND package_path/xxx
. Without specifying the package_path ./
and just running go COMMAND xxx
, the compiler assumes that the module xxx is located in GOROOT, and throws error package xxx is not in GOROOT (path/to/GOROOT/src/xxx)
because it doesn't exist.
This behavior is expected because the package we are working with is not part of the Go SDK, i.e., not in GOROOT
. The package we are working with will either end up in the go workspace or in the current working directory. Running go install
compiles and puts an executable binary in $GOBIN
(a.k.a $GOPATH/bin
- here $GOPATH
is the Go workspace). Running go build
from inside a package compiles and puts an execuatble in that directory.
You haven't listed the files inside the server/
package and which file has the main function, so I'll emulate 3 workflows of a calculator each demonstrating more complexity. The last workflow is similar to your directory structure.
Directory Structure
Version 1:
Getting started with packages
Basic functionality
calculatorv1
├── go.mod <- go mod init github.com/yourname/calculatorv1
└── basic/
├── add.go
├── add_test.go
├── main.go
├── multiply.go
└── multiply_test.go
Version 2:
More functionality
Multiple packages
calculatorv2
├── go.mod <- go mod init github.com/yourname/calculatorv2
├── main.go
└── basic/
│ ├── add.go
│ ├── add_test.go
│ ├── multiply.go
│ └── multiply_test.go
└─── advanced/
├── square.go
└── square_test.go
Version 3:
Even more functionality
Nested packages
calculatorv3
├── go.mod <- go mod init github.com/yourname/calculatorv3
├── main.go
└── basic/
│ ├── add.go
│ ├── add_test.go
│ ├── multiply.go
│ └── multiply_test.go
└─── advanced/
├── square.go
├── square_test.go
└── scientific/
├── declog.go
└── declog_test.go
Workflow
Note: Substitute xxx
with basic
, advanced
, or advanced/scientific
depending on the version you're working with.
Initialize Go module in the project directory (one of
calculatorv1
,calculatorv2
, orcalculatorv3
) usinggo mod init
Run tests
go test -v ./...
(from the project root, recursively execute all test suites)OR
go test -v ./xxx
(from the project root, run the test suite in package "xxx")OR
cd xxx/ go test -v # (from inside the package)
Compile and execute package
go run ./...
(プロジェクトルートから、.go
テストを除くすべてのファイルを再帰的に実行します)または
go run ./xxx
(プロジェクト ルートから、.go
テストを除く「xxx」パッケージ内のすべてのファイルを実行します)または
cd xxx go run . # (from inside the package)
注記: メインパッケージ内のファイル、つまり宣言を持つファイルのみが実行可能です
package main
。つまり、 はgo run ./xxx
バージョン1でのみ動作し、バージョン2と3では動作しません。そのため、バージョン2と3の場合は、代わりに以下を実行します。go run main.go
コード
不完全な部分を埋めるのは非常に簡単
バージョン 1
追加する
package main
func addition(x int, y int) int {
return x + y
}
追加テスト
package main
import "testing"
func TestAdd(t *testing.T) {
t.Run("adding two positive numbers", func(t *testing.T) {
sum := addition(2, 2)
expected := 4
if sum != expected {
t.Errorf("Expected %d; but got %d", expected, sum)
}
})
t.Run("adding two negative numbers", func(t *testing.T) {
sum := addition(-3, -4)
expected := -7
if sum != expected {
t.Errorf("Expected %d; but got %d", expected, sum)
}
})
t.Run("adding one positive and one negative integer", func(t *testing.T) {
sum := addition(1, -3)
expected := -2
if sum != expected {
t.Errorf("Expected %d; but got %d", expected, sum)
}
})
}
メイン.go
package main
import "fmt"
func main() {
var num1 int = 1
var num2 int = 2
sum := addition(num1, num2)
product := multiplication(num1, num2)
fmt.Printf("The sum of %d and %d is %d\n", num1, num2, sum)
fmt.Printf("The multiplication of %d and %d is %d\n", num1, num2, product)
}
バージョン2
メイン.go
package main
import (
"fmt"
"github.com/yourname/calculatorv2/basic"
"github.com/yourname/calculatorv2/advanced"
)
func main() {
var num1 int = 1
var num2 int = 2
product := basic.Multiplication(num1, num2)
square := advanced.Square(num2)
fmt.Printf("The product of %d and %d is %d\n", num1, num2, product)
fmt.Printf("The square of %d is %d\n", num2, square)
}
乗算する
package basic
func Multiplication(x int, y int) int {
return x * y
}
乗算テスト.go
package basic
import "testing"
func TestMultiply(t *testing.T) {
t.Run("multiplying two positive numbers", func(t *testing.T) {
sum := Multiplication(2, 2)
expected := 4
if sum != expected {
t.Errorf("Expected %d; but got %d", expected, sum)
}
})
t.Run("multiplying two negative numbers", func(t *testing.T) {
sum := Multiplication(-3, -4)
expected := 12
if sum != expected {
t.Errorf("Expected %d; but got %d", expected, sum)
}
})
t.Run("multiplying one positive and one negative integer", func(t *testing.T) {
sum := Multiplication(1, -3)
expected := -3
if sum != expected {
t.Errorf("Expected %d; but got %d", expected, sum)
}
})
}
スクエアゴー
package advanced
func Square(x int) int {
return x * x
}
バージョン3
メイン.go
package main
import (
"fmt"
"github.com/yourname/calculatorv3/basic"
"github.com/yourname/calculatorv3/advanced"
"github.com/yourname/calculatorv3/advanced/scientific"
)
func main() {
var num1 int = 1
var num2 int = 2
var num3 float64 = 2
product := basic.Multiplication(num1, num2)
square := advanced.Square(num2)
decimallog := scientific.DecimalLog(num3)
fmt.Printf("The product of %d and %d is %d\n", num1, num2, product)
fmt.Printf("The square of %d is %d\n", num2, square)
fmt.Printf("The decimal log (base 10) of %f is %f\n", num3, decimallog)
}
スクエアゴー
package advanced
func Square(x int) int {
return x * x
}
デクロッグ
package scientific
import "math"
func DecimalLog(x float64) float64 {
return math.Log10(x)
}
デクロッグテスト
package scientific
import "testing"
func TestDecimalLog(t *testing.T) {
t.Run("adding two positive numbers", func(t *testing.T) {
sum := DecimalLog(100)
expected := 2.0
if sum != expected {
t.Errorf("Expected %f; but got %f", expected, sum)
}
})
t.Run("adding two negative numbers", func(t *testing.T) {
sum := DecimalLog(10)
expected := 1.0
if sum != expected {
t.Errorf("Expected %f; but got %f", expected, sum)
}
})
}