Based on experimentation and from looking at the language spec, I want to try to define how Go packaging works. I haven’t found Go’s packaging and import mechanism that intuitive so far. I think this is probably due to stale assumptions based on my experience in other languages like Python, Java and C++, and also for the fact that the language spec leaves certain decisions open to the toolchain. Plus, the toolchain provides several commands for building and running (build, install, and run), and several ways to specify what to build (by package, by file path or using wildcards).
So, here are the rules based on my current understanding. First, for a library:
- The name of the containing folder becomes the name of the binary library file. E.g. source files under
mystuffare compiled into
- The containing folder’s name and its path relative to
$GOPATH/src, form the package import-path. E.g. you would import the
github.com/munckymagik/mystuff, if this is the path to the
.afile relative to
- All source files within the package must declare the same package-name; but, this name does not need to be the same as the containing folder name. E.g. within the
mystufffolder, I could use the package-name
mystuffxxxwithin the source files. Then in client code, I would still import the package as
github.com/munckymagik/mystuff, but I would refer to its symbols using the package-name, like:
mystuffxxx.SymbolName. However, the convention (unsurprisingly) is to use a package-name that matches the containing folder name.
- The individual names of the source files in the containing folder have no effect on package naming or importing, nor in resolving symbols.
- The only reason to split package source into several files is to avoid having excessively large files.
Then for executables:
- Source files that compile to executables must contain a
main()function and must be declared in the
- An executable source file can be built, run or installed by specifying its package name. E.g.
go install path/to/myexe, in this case only one file within the
myexefolder may contain a
mainfunction, otherwise go will report a “main redeclared” error.
- An executable source file can be built or run directly using
go run path/to/myexe/filename.go. In this case, many files within the
myexefolder may contain
mainfunctions, go ignores the other files in the folder unless you list them on the command-line too.
- Within a folder containing one or more executable source files, shared source code may be placed into separate files. These files must also be declared in the
It’s actually quite simple, if you think about folders as the unit-of-packaging and make sure that you use package names that match the containing folder names, except for folders that contain executable
This is just my current understanding, so if you think I have made a mistake, please do tell me.