I have a directory structure like this:
Animal/
dog/
chiwawa.go
rabbit.go
Both chiwawa.go
and rabbit.go
are packaged named: "package animal" at the top of the file. However when I try to use a variable var Food = apple
from chiwawa.go
in rabbit.go
, I get error - undefined: Food
.
I don't have any problems when I place chiwawa.go
directly under Animal
without the dog
directory.
Is this intentional in Go? Can I work around this while retaining the package names and directory structure?
The go tool is designed to work with open source code maintained in public repositories. Although you don't need to publish your code, the model for how the environment is set up works the same whether you do or not.
Go code must be kept inside a workspace. A workspace is a directory hierarchy with three directories at its root:
- src contains Go source files organized into packages (one package per directory),
- pkg contains package objects, and
- bin contains executable commands.
The go tool builds source packages and installs the resulting binaries to the pkg and bin directories.
The src subdirectory typically contains multiple version control repositories (such as for Git or Mercurial) that track the development of one or more source packages.
To give you an idea of how a workspace looks in practice, here's an example:
bin/ hello # command executable outyet # command executable pkg/ linux_amd64/ github.com/golang/example/ stringutil.a # package object src/ github.com/golang/example/ .git/ # Git repository metadata hello/ hello.go # command source outyet/ main.go # command source main_test.go # test source stringutil/ reverse.go # package source reverse_test.go # test source
This workspace contains one repository (example) comprising two commands (hello and outyet) and one library (stringutil).
A typical workspace would contain many source repositories containing many packages and commands. Most Go programmers keep all their Go source code and dependencies in a single workspace.
For the Go tools, all the Go source files for a Go package should be in the same directory.
It is intentional. Packages in Go are imported using a directory path. So, "animal" and "animal/dog" are two different packages even if you give them the same package name.
To demonstrate this, I wrote the following example set of files:
~/go/src/test/
├── animal
│ ├── animal.go
│ └── dog
│ └── dog.go
└── test.go
animal/animal.go
package animal
type Species string
animal/dog/dog.go
package animal
// In package "animal" importing a package "animal"
import "test/animal"
type Dog struct {
Species animal.Species
Breed string
}
test.go
package main
import (
"fmt"
"test/animal/dog"
)
func main() {
d := animal.Dog{}
fmt.Printf("%#v", d)
}
Notice that dog.go imports the "test/animal" package and references it as "animal".
Furthermore notice that test.go imports "test/animal/dog" to get access to the "Dog" struct type. If it imports, "test/animal", the error (undefined: animal.Dog) is generated.