Types
A type determines a set of values together with operations and methods specific to those values. A type may be denoted by a type name, if it has one, which must be followed by type arguments if the type is generic.
(and jumping ahead a bit)
Predeclared types, defined types, and type parameters are called named types. An alias denotes a named type if the type given in the alias declaration is a named type.
For now, we’re going to skip over the last part of this quotation, which relates to generics, since that’s a whole new can of worms.
Today, I want to call out the phrase “A type may be denoted by a type name, if it has one”. When does a type have a name? And how do you use a type that doesn’t have a name?
Most often, you’re likely to be dealing with types by their names. Names such as int
, byte
, or string
, or user-defined types such as Person
or BlogPost
or apiError
.
But sometimes we use anonymous, or unnamed types, too. This is most common with certain composite types, such as slices, arrays, and maps. []byte
, for example, is an anonymous type, representing a byte slice. We could also have a named type with the same structure:
type ByteSlice []byte
But more on that another day.
Anonymous types can also be used in variable declarations, even for complex types, such as structs:
var x = struct {
Name string
Age int
}{
Name: "Bob",
Age: "43",
}
This is often very cumbersome to use, as you must re-write the entire struct defintion every time you want to access the type, so this particular use of anonymous types is a bit discouraged. Although, there are times when it can be appropriate, as I recently discussed on my YouTube channel in an interview with Mechiel Lukkien: Interactive Go Code Review: mox mail server
And finally, one last example for now of an anonymous type, is the one I actually discussed in yesterday’s email, the anonymous pointer type! I.e. *string
is a type, a pointer to a string, but it is unnamed. It is perfectly valid to create a custom type of this, eh, type…
type stringPtr *string
Although, the cases where it’s useful to create a named type to a pointer type are a bit rare, and it’s often confusing to do so. So I don’t generally recommend doing that. :)
Quotes from The Go Programming Language Specification, Version of January 19, 2023