软件包命名:错误导出变量

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?

How to Write Go Code

Workspaces

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.