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