← Omar Abdulaziz

Where Go Looks for Your Code

First of all, I want to mention that this not discussing the remote module/packages import, it is about the code you write separated into files, packages, or modules.

Coming from languages like Python and JavaScript. I found it difficult to understand the importing code system in Golang. it takes me some time to go through articles and videos to get it. So I wanted to summarize what I learned for future reference and share it may it help someone.

I am still new at Go so I will appreciate it if you have any comments.

Introduction

What is this article about? once you get your hands dirty with Go and start a new scaling project you will surely need to separate your code into files to be more organized, or sometimes you will need to write a reusable package that you will use in multiple projects. And that is what we going to discuss my friend.

1. Importing from another file in the same package

There is nothing special to do in this situation. Go deals with multiple files belonging to the same package as one file. you just need to call the Variable or Function by its name.

// foo.go
package main

func greet() {
	println("hello")
}
// bar.go
package main

func main() {
  greet()
}

2. GOPATH Import

For some reason relative importing is not supported in Go instead you will need to use an absolute path for the package you want to import according to any of the paths stored in the GOPATH environment variable.

To add your project path to GOPATH:

export GOPATH=$GOPATH:/absolute/path/to/your/project

Let’s assume your project structure is:

project/
|--pkg/
	|--util.go
|--main.go
|--go.mod

if you add the path to the GOPATH, you can easily import utils from the package into the main:

// project/pkg/util.go
package util

func Inc(num int) int {
	return num + 1
}
// project/main.go
package main

import "pkg/util"

func main() {
	println(util.Inc(1))
}

it looks like the GOPATH is not recommended since go11

2. Import a package in the same module

In some cases, you will need to separate your code into packages so it will be more accessible and reusable in different projects.

Let’s assume a project structure is:

great_app/
|--pkg/
	|--util.go
|--main.go
|--go.mod

a super genius package that increments a given number

// project/pkg/util.go
package math

func Inc(num int) int {
	return num + 1
}

in your main file, the import should be the whole name of the module given during init + the relative path to the package according to the module root.

if you init the module like this:

go mod init github.com/user/great_app

your import should be:

// project/main.go
package main

import "github.com/user/great_app/pkg"

func main() {
	println(math.Inc(1))
}

Note: A package in Go is more like a directory, not a file. so in the import statement, it imports the directory the package files are in. and uses the name of the package not the file or directory as a namespace to access the methods in the package.

3. Import a package from another module

Another use case is if you have two projects neither of them is not published yet and one of them is dependent on the other. so how you can import?

All you will need to do besides the regular module import is to replace the second module name with the absolute local path.

For example:

project1/
	main.go
	go.mod # github.com/user/project1
project2/
	main.go
	go.mod # github.com/user/project2

on one of the projects

cd project1/
go mod edit -replace github.com/user/project2=/absolute/path/to/the/other/project
go get github.com/user/project2

and now you can import like that

import "github.com/user/project2"

mod1 import mod0

# in mod1
replace <mod0> <path>

and even if mod2 importing mod1, you also need to replace it, as it can be found as indirect deps


it is not required to have a matching go version in your mod file and on your local. but must the installed version be newer