Imports
source ↗Imports
Import renaming
Package imports shouldn’t normally be renamed, but there are cases where they must be renamed or where a rename improves readability.
Local names for imported packages must follow the guidance around package naming, including the prohibition on the use of underscores and capital letters. Try to be consistent by always using the same local name for the same imported package.
An imported package must be renamed to avoid a name collision with other imports. (A corollary of this is that good package names should not require renaming.) In the event of a name collision, prefer to rename the most local or project-specific import.
Generated protocol buffer packages must be renamed to remove underscores from
their names, and their local names must have a pb suffix. See
proto and stub best practices for more
information.
// Good:
import (
foosvcpb "path/to/package/foo_service_go_proto"
)
Lastly, an imported, non-autogenerated package can be renamed if it has an
uninformative name (e.g. util or v1) Do this sparingly: do not rename the
package if the code surrounding the use of the package conveys enough context.
When possible, prefer refactoring the package itself with a more suitable name.
// Good:
import (
core "github.com/kubernetes/api/core/v1"
meta "github.com/kubernetes/apimachinery/pkg/apis/meta/v1beta1"
)
If you need to import a package whose name collides with a common local variable
name that you want to use (e.g. url, ssh) and you wish to rename the
package, the preferred way to do so is with the pkg suffix (e.g. urlpkg).
Note that it is possible to shadow a package with a local variable; this rename
is only necessary if the package still needs to be used when such a variable is
in scope.
Import grouping
Imports should be organized into the following groups, in order:
-
Standard library packages
-
Other (project and vendored) packages
-
Protocol Buffer imports (e.g.,
fpb "path/to/foo_go_proto") -
Import for side-effects (e.g.,
_ "path/to/package")
// Good:
package main
import (
"fmt"
"hash/adler32"
"os"
"github.com/dsnet/compress/flate"
"golang.org/x/text/encoding"
"google.golang.org/protobuf/proto"
foopb "myproj/foo/proto/proto"
_ "myproj/rpc/protocols/dial"
_ "myproj/security/auth/authhooks"
)
Import “blank” (import _)
Packages that are imported only for their side effects (using the syntax import _ "package") may only be imported in a main package, or in tests that require
them.
Some examples of such packages include:
-
image/jpeg in image processing code
Avoid blank imports in library packages, even if the library indirectly depends on them. Constraining side-effect imports to the main package helps control dependencies, and makes it possible to write tests that rely on a different import without conflict or wasted build costs.
The following are the only exceptions to this rule:
-
You may use a blank import to bypass the check for disallowed imports in the nogo static checker.
-
You may use a blank import of the embed package in a source file which uses the
//go:embedcompiler directive.
Tip: If you create a library package that indirectly depends on a side-effect import in production, document the intended usage.
Import “dot” (import .)
The import . form is a language feature that allows bringing identifiers
exported from another package to the current package without qualification. See
the language spec for more.
Do not use this feature in the Google codebase; it makes it harder to tell where the functionality is coming from.
// Bad:
package foo_test
import (
"bar/testutil" // also imports "foo"
. "foo"
)
var myThing = Bar() // Bar defined in package foo; no qualification needed.
// Good:
package foo_test
import (
"bar/testutil" // also imports "foo"
"foo"
)
var myThing = foo.Bar()