structs and named types
I recently blogged about patterns in go
and in that we saw how methods on structs can be used to implement interfaces. Specifically the
Structs, are not the only way to achieve this; all named types offer similar functionality. First - some definitions from the golang spec…
“A struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (AnonymousField). Within a struct, non-blank field names must be unique.” - golang spec
“A type determines the set of values and operations specific to values of that type. Types may be named or unnamed. Named types are specified by a (possibly qualified) type name; unnamed types are specified using a type literal, which composes a new type from existing types.” - golang spec
Essentially this boils down to:
- struct are a sequence of fields, each field has a type.
- named types create a new type, using an existing underlying type.
Here the type is
struct but we can create a new named type, with the underlying type of
But named types don’t exclusively apply to the
struct underlying type, any type can become a named type. If we take the example from patterns in go:
structs and a
mutator function type to create a safe representation of a string, that won’t accidentally print a password to logs.
We don’t have to use
struct as the underlying type to hold the
string, we can actually use a
string to represent a
In this small go program the named type is
password which has the underlying type
string and implements the
Stringer interface. Running it and the output is…
password: ********************* instead of
We can see that the
String() method of the
password type was called, and printed the safe version of the underlying
There is a gotcha though, as named types are types if we have the type
username with an underlying type of
string, and introduce this to our program:
The problem here is that if we try and compile this program we get the following error:
password types have the underlying type
string, they are not of the same type, and more importantly they are not of the type
string. We would have to type cast them to
string to be able to use them here.
Or instead we can use their named types…
This leads to incredible power, when using types idiomatically!