[GO language] Organize the behavior of import in places other than GOPATH

I often get hooked when importing in a place other than $ GOPATH. That is because there are the following patterns.

For each of these, sort out how import is different. (GO version is assumed to be 1.14)

Rough summary

When I write the outline of the conclusion, it looks like the following

Introduction

environment

Switching between GOPATH mode and module mode

GOPATH mode and module mode switch depending on the presence or absence of the go.mod file

Import of external package

Import of external packages in GOPATH mode

Directory structure

.
└── main.go

main.go

package main

import (
	"fmt"
	"github.com/antonholmquist/jason" //Importing external packages
)

func main() {
	v, _ := jason.NewObjectFromBytes([]byte(`{"Name": "fetaro"}`))
	fmt.Println(v)
}

Where are you going to look for?

$GOPATH/src/

Specifically, $ GOPATH / src / github.com/antonholmquist/jason

What if there is no package here

cannot find package error

main.go:5:2: cannot find package "github.com/antonholmquist/jason" in any of:
	/usr/local/Cellar/go/1.14.3/libexec/src/github.com/antonholmquist/jason (from $GOROOT)
	/Users/tetsutaro.watanabe/go/src/github.com/antonholmquist/jason (from $GOPATH)

How to place the package?

go get

Specifically, go get github.com/antonholmquist/jason

Import of external packages in module mode

Directory structure

.
├── go.mod ←go.I put the mod file, so it goes into module mode
└── main.go

main.go

package main

import (
	"fmt"
	"github.com/antonholmquist/jason" //Importing external packages
)

func main() {
	v, _ := jason.NewObjectFromBytes([]byte(`{"Name": "fetaro"}`))
	fmt.Println(v)
}

go.mod

module hoge

go 1.14

Where are you going to look for?

$GOPATH/pkg/mod

Specifically, /Users/tetsutaro.watanabe/go/pkg/mod/github.com/antonholmquist/jason\@v1.0.0/

What if there is no package here

It will be downloaded without permission.

If you do go run main.go while it has not been downloaded yet, it will be downloaded and then executed as shown below.

$ go run main.go
go: finding module for package github.com/antonholmquist/jason
go: found github.com/antonholmquist/jason in github.com/antonholmquist/jason v1.0.0 ← Download result
{"Name":"fetaro"}← Execution result

Once downloaded, go.mod will be rewritten

Rewritten go.mod

module hoge

go 1.14

require github.com/antonholmquist/jason v1.0.0 // indirect

Internal package import

Import internal packages in GOPATH mode

Directory structure

.
├── main.go
└── mypkg ← Internal package
    └── bar.go

main.go

package main

import (
	"./mypkg" //Import internal packages
)

func main() {
	mypkg.PrintBar()
}

bar.go

package mypkg

import "fmt"

func PrintBar(){
	fmt.Println("bar")
}

Where to go to look

./mypkg with a relative path from main.go

What if there is no package here

cannot find package error

main.go:4:2: cannot find package "." in:
	/Users/tetsutaro.watanabe/git/golab3/mypkg

Import internal packages in module mode

Directory structure

.
├── go.mod ←go.Module mode because there is a mod
├── main.go
└── mypkg ← Internal library
    └── bar.go

main.go

package main

import (
	"mymodule/mypkg" //← go here.Module name written in mod+Make it a package name
)

func main() {
	mypkg.PrintBar()
}

go.mod

module mymodule

go 1.14

bar.go

package mypkg

import "fmt"

func PrintBar(){
	fmt.Println("bar")
}

Where to go to look

This is difficult. In module mode, " mymodule / mypkg " specified in import is a concatenation of module and package.

Specifically, you'll be looking for (module name in go.mod) + (relative path to the package from where go.mod is).

In this example, mymodule is the module and / mypkg is the relative path from the directory containing "go.mod with module mymodule".

What if there is no package here

Get an error

main.go:4:2: package mymodule/mypkg is not in GOROOT (/usr/local/Cellar/go/1.14.3/libexec/src/mymodule/mypkg)

Experiment of places to go to look for 1

Case where go.mod is higher than main.go

For example, in the case of the following directory structure

.
├── c_pkg
│   ├── d_pkg
│   │   └── bar.go
│   └── main.go
└── go.mod

If you specify module a_module / b_module in go.mod, In main.go, it can be read by import" a_module / b_module / c_pkg / d_pkg "

Experiment of places to go to look for 2

Common cmd and internal configurations

.
├── cmd
│   └── main.go
├── go.mod
└── internal
    └── lib.go

go.mod

module github.com/fetaro/my_module

go 1.14

main.go

package main

import (
    "github.com/fetaro/my_module/internal"
)

func main() {
    internal.PrintHoge()
}

lib.go

package internal

import "fmt"

func PrintHoge(){
    fmt.Println("hoge")
}

Recommended Posts

[GO language] Organize the behavior of import in places other than GOPATH
Check the behavior of destructor in Python
Differences in the behavior of each LL language when the list index is skipped
I wrote the hexagonal architecture in go language
About the behavior of Model.get_or_create () of peewee in Python
Ruby expert learned the basic grammar of Go language
About the uncluttered arrangement in the import order of flake8
Features of Go language
A note on the default behavior of collate_fn in PyTorch
[Note] Import of a file in the parent directory in Python
Hello World in GO language
Organize useful blogs in the field of data science (overseas & Japan)
Read the config file in Go language! Introducing a simple sample
The story that inheritance behavior is quite different in each language
Create a function to get the contents of the database in Go