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 Stringer interface.
Structs, are not the only way to achieve this; all named types offer similar functionality. First - some definitions from the golang spec…
struct types
“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
named types
“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.
code
| |
Here the type is struct but we can create a new named type, with the underlying type of struct:
| |
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:
safe.go
| |
This uses 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 string.
main.go
| |
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 password: super-secret-password
We can see that the String() method of the password type was called, and printed the safe version of the underlying string value.
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:
main.go
| |
The problem here is that if we try and compile this program we get the following error:
| |
Even though username and 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!