Working with versioned imports

October 17, 2024

We’re continuing today our discussion of imports. Yesterday we left off with using explicit package names in an import clause when the package name differs from the last element of the import path.

Is that the only reason to explicitly name your imports? No. Sometimes you need to disambiguate between two imports with the same package name. Or maybe you just like a shorter name.

import (
  log "github.com/sirupsen/logrus" // Shorter names are nice

  stdlog "log" // Oh, but we need to reference this package, too
)

There is one exception to the rule “Name your packages the same as the last element of your import path,” though: v2+ releases.

import (
  "math/rand/v2"
)

When you release a Go module with a major version of 2 or greater, that version is appended as the last element of the import path, but in this case, convention is to use the second-to-last path element as the name. In the above example, the package is called math. This leads to another rule: Don’t ever name your packages vX where X is an integer. It will confuse everyone! Fortunately, I’ve only run into this once in the real world.

Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Relative imports

Newcomers to Go often try to use relative imports, and then are usually bitten by random weird problems. They seem to work sometimes, and not other times. What’s the deal? import "./foo" Import declarations … The interpretation of the ImportPath is implementation-dependent but it is typically a substring of the full file name of the compiled package and may be relative to a repository of installed packages. Okay. So this bit of the spec doesn’t help a whole lot.


Import declarations

Today we have a very important topic… Import declarations An import declaration states that the source file containing the declaration depends on functionality of the imported package (§Program initialization and execution) and enables access to exported identifiers of that package. The import names an identifier (PackageName) to be used for access and an ImportPath that specifies the package to be imported. ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .


Import cycles

First off, the spec provides an example of how to reference a symbol in an imported package, using different import alias options. I’ve already provided my own examples earlier, and it’s pretty straight forward, so we’ll just breeze through this part. Import declarations … Consider a compiled a package containing the package clause package math, which exports function Sin, and installed the compiled package in the file identified by "lib/math". This table illustrates how Sin is accessed in files that import the package after the various types of import declaration.

Get daily content like this in your inbox!

Subscribe