129

I am having difficulty in importing a local go file into another go file.

My project structure is like something below

-samplego
--pkg
--src
---github.com
----xxxx
-----a.go
-----b.go
--bin

I am trying to import a.go inside b.go. I tried the following,

import "a"
import "github.com/xxxx/a"

None of these worked..I understand I have to meddle up with GOPATH but I couldn't get it right. Presently my GOPATH is pointing to samplego(/workspace/samplego).I get the below error

cannot find package "a" in any of:
/usr/local/go/src/pkg/a (from $GOROOT)
/workspace/samplego/src/a (from $GOPATH)

Also, how does GOPATH work when these source files are imported into another project/module? Would the local imports be an issue then? What is the best practice in this case - is it to have just one go file in module(with associated tests)?

g0c00l.g33k
  • 2,458
  • 2
  • 31
  • 41
  • 1
    Any number of files in a directory are part of the same package from the start. (And they need to have the same `package a` declaration at the top.) – twotwotwo Nov 15 '14 at 03:23
  • Thanks @twotwotwo...Could you let me know how to solve the above issue? Also, when we have multipe go files in a package should the import follow full path eg. github.com/xxxx/a or just a would do – g0c00l.g33k Nov 15 '14 at 03:50
  • For Go modules, files in the same directory are still part of the same package, still need to have the same package name (e.g., `package foo`), and still do not need to directly import each other. This [answer](https://stackoverflow.com/a/57314494/11210494) covers this a bit more for Go modules, including how to import packages in the same module under Go modules. – thepudds Aug 01 '19 at 19:59

9 Answers9

117

Any number of files in a directory are a single package; symbols declared in one file are available to the others without any imports or qualifiers. All of the files do need the same package foo declaration at the top (or you'll get an error from go build).

You do need GOPATH set to the directory where your pkg, src, and bin directories reside. This is just a matter of preference, but it's common to have a single workspace for all your apps (sometimes $HOME), not one per app.

Normally a Github path would be github.com/username/reponame (not just github.com/xxxx). So if you want to have main and another package, you may end up doing something under workspace/src like

github.com/
  username/
    reponame/
      main.go   // package main, importing "github.com/username/reponame/b"
      b/
        b.go    // package b

Note you always import with the full github.com/... path: relative imports aren't allowed in a workspace. If you get tired of typing paths, use goimports. If you were getting by with go run, it's time to switch to go build: run deals poorly with multiple-file mains and I didn't bother to test but heard (from Dave Cheney here) go run doesn't rebuild dirty dependencies.

Sounds like you've at least tried to set GOPATH to the right thing, so if you're still stuck, maybe include exactly how you set the environment variable (the command, etc.) and what command you ran and what error happened. Here are instructions on how to set it (and make the setting persistent) under Linux/UNIX and here is the Go team's advice on workspace setup. Maybe neither helps, but take a look and at least point to which part confuses you if you're confused.

Community
  • 1
  • 1
twotwotwo
  • 28,310
  • 8
  • 69
  • 56
  • 1
    goimports was quite helpful :) – g0c00l.g33k Nov 15 '14 at 14:44
  • 1
    If you are having trouble running multiple files in the main package, see [this answer](http://stackoverflow.com/a/28081554/616644). – Rick Smith May 22 '16 at 15:30
  • I added the same `package main` declaration to all files in the same directory, but I have the `undefined` error, `main.go` cannot see functions from file `controllers.go` which is in the same directory. – ame Nov 08 '18 at 12:17
  • 3
    @AlexChaliy If you're using `go run`, you may need to explicitly pass both filenames to it, or switch to putting them in a package in your GOPATH and `go build`ing it. Also double-check for common errors unrelated to package structure (like a typoed name). If none of that solves it, I'd open a new question with all the detail you can; it might take a lot of discussion of precisely how _your_ dir, files, etc. look to solve, and since it'd be specifically about your setup a new question seems like the best venue for that. – twotwotwo Nov 08 '18 at 18:20
  • Excellent answer, learned many new things in a single answer. Thanks. – MohitC Dec 01 '22 at 12:47
63

No import is necessary as long as you declare both a.go and b.go to be in the same package. Then, you can use go run to recognize multiple files with:

$ go run a.go b.go
Jason Kao
  • 1,024
  • 11
  • 15
  • 1
    this is what's needed for a quick and dirty exploration. Also worth mentioning that the package name at the top of each file needs to be 'main' for this to work. – Hansang Nov 04 '22 at 04:25
20

./main.go (in package main)
./a/a.go (in package a)
./a/b.go (in package a)

in this case:
main.go import "./a"

It can call the function in the a.go and b.go,that with first letter caps on.

user2889485
  • 209
  • 1
  • 2
8

If none of the above answers works,

Just try,

go run .

for production,

go build

This will take care of all the .go files in the folder.

RG_RG
  • 349
  • 5
  • 8
2

I just wanted something really basic to move some files out of the main folder, like user2889485's reply, but his specific answer didnt work for me. I didnt care if they were in the same package or not.

My GOPATH workspace is c:\work\go and under that I have

/src/pg/main.go      (package main)
/src/pg/dbtypes.go   (pakage dbtypes)

in main.go I import "/pg/dbtypes"

Dave Pile
  • 5,559
  • 3
  • 34
  • 49
1

As people mentioned previously, there is no need to use any imports. A lot of people mention that using go run is possibe when you mention most files, however when having multiple .go-files in the same dir it can be cumbersome. Therefore using go run *.go is what I usually do.

Thorvald
  • 546
  • 6
  • 18
-1

As I understand for packages in your project subfolders it's possible now to do, just need to add "." in front of module, like . "github.com/ilyasf/deadlock-train/common" where github.com/ilyasf/deadlock-train my main module name and common is just package from /common subfolder inside project.

-1

go1.19.1 version here. I've just had the same issue, discovered that you must simply do: import (a "github.com/xxxx")

-1

You can go to the correct folder and execute: $ go run *.go

As long as the code only 1 main function in all files it works perfect!

DevDaniels
  • 29
  • 1
  • 5