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!