If what you said was true, then your function call would actually be 1-foodir.FooFunc()
instead of foopkg.FooFunc()
. Instead, go sees the package name in 2-foofile.go and imports it as foopkg
because in go the name of the package is exactly what comes after the words package
at the top of .go files, provided it is a valid identifier.
The only use of the directory is for collecting a set of files that share the same package name. This is reiterated in the spec
A set of files sharing the same PackageName form the implementation of a package. An implementation may require that all source files for a package inhabit the same directory.
In go, it is convention that the directory match the package name but this doesn’t have to be the case, and often it is not with 3rd party packages. The stdlib does do a good job of sticking to this convention.
Now where directories do come into play is the import path. You could have 2 packages named ‘foo’ in your single binary as long as they had different import paths, i.e.
/some/path/1/foo
and /some/path/2/foo
And we can get really swanky and alias the imports to whatever we wanted, for example I could do
import (
bar "/some/path/1/foo"
baz "/some/path/2/foo"
)
Again the reason this works is not because the package name has to be unique, but the package import path must be unique.
Another bit of insight to glean from this statement is — within a directory, you cannot have two package names. The go compiler will throw an error stating it cannot load package
and that it found packages foo (foo.go) and bar (bar.go)
.
See https://golang.org/doc/code.html#PackageNames for more information.