Qualified identifiers

September 15, 2023

One of the features of Go I found most discomforting when I started using the language, was that of qualifiers. Depending on which previous languages you may have experience with, you may find them perfectly natural, or entirely strange. Let’s see what they are…

Qualified identifiers

A qualified identifier is an identifier qualified with a package name prefix. Both the package name and the identifier must not be blank.

QualifiedIdent = PackageName "." identifier .

A qualified identifier accesses an identifier in a different package, which must be imported. The identifier must be exported and declared in the package block of that package.

math.Sin // denotes the Sin function in package math

Let’s illustrate with a complete (but trivial) example. Suppose we have a package foo:

package foo

const Foo = "the fooiest"

Now to the exported symbol Foo from another package, we need to both import the foo package, and use a qualified identifier:

package main

import "foo"

var x = foo.Foo

By way of comparison, this the rough equivalent of the following in JavaScript, which doesn’t use qualifiers.

import { foo } from "foo";

var x = foo;

As an aside, you can avoid the use of qualified identifiers in Go by using “dot imports”, but it’s generally frowned upon (and I honestly wish this wasn’t possible). Please don’t do this, but here’s what it would look like:

package main
import . "foo"

var x = Foo

Quotes from The Go Programming Language Specification Version of August 2, 2023

Share this

Related Content

Uniqueness of identifiers

Uniqueness of identifiers Given a set of identifiers, an identifier is called unique if it is different from every other in the set. Two identifiers are different if they are spelled differently, or if they appear in different packages and are not exported. Otherwise, they are the same. This is pretty simple stuff, but it’s obviously worth being explicit. foo and bar are obviously different identifiers. Further, a in package foo, and a in package bar are different identifiers, because although they are spelled the same, they are not exported, and are in different packages.

Lexical elements: Identifiers

Identifiers Identifiers name program entities such as variables and types. An identifier is a sequence of one or more letters and digits. The first character in an identifier must be a letter. identifier = letter { letter | unicode_digit } . So in other words, every identifier must begin with a letter, followed by zero or more letters and/or digits. Pretty simple. The spec offers a few examples a _x9 ThisVariableIsExported αβ That second one looks a bit suspicious.

Zero values of slices and maps

Composite literals … Note that the zero value for a slice or map type is not the same as an initialized but empty value of the same type. Let’s look at examples so we can understand exactly what is being stated here. Recall that when you declare a variable of a given type, the default value is the zero value for the type: var s1 []string // Zero value for slice var m1 map[string]int // Zero value for map What the spec is telling us is that the zero value of a slice or map is not the same as an initialized, but empty, slice or map: