Structs contains various utilities to work with Go (Golang) structs. It was
initially used by me to convert a struct into a map[string]interface{}. With
time I've added other utilities for structs. It's basically a high level
package based on primitives from the reflect package. Feel free to add new
functions or improve the existing code.
go get github.com/jcarter3/structsJust like the standard lib strings, bytes and co packages, structs has
many global functions to manipulate or organize your struct data. Lets define
and declare a struct:
typeServerstruct {
Namestring`json:"name,omitempty"`IDintEnabledboolusers []string// not exported
http.Server// embedded
}
server:=&Server{
Name: "gopher",
ID: 123456,
Enabled: true,
}// Convert a struct to a map[string]interface{}// => {"Name":"gopher", "ID":123456, "Enabled":true}m:=structs.Map(server)
// Convert the values of a struct to a []interface{}// => ["gopher", 123456, true]v:=structs.Values(server)
// Convert the names of a struct to a []string// (see "Names methods" for more info about fields)n:=structs.Names(server)
// Convert the values of a struct to a []*Field// (see "Field methods" for more info about fields)f:=structs.Fields(server)
// Return the struct name => "Server"n:=structs.Name(server)
// Check if any field of a struct is initialized or not.h:=structs.HasZero(server)
// Check if all fields of a struct is initialized or not.z:=structs.IsZero(server)
// Check if server is a struct or a pointer to structi:=structs.IsStruct(server)The structs functions can be also used as independent methods by creating a new
*structs.Struct. This is handy if you want to have more control over the
structs (such as retrieving a single Field).
// Create a new struct type:s:=structs.New(server)
m:=s.Map() // Get a map[string]interface{}v:=s.Values() // Get a []interface{}f:=s.Fields() // Get a []*Fieldn:=s.Names() // Get a []stringf:=s.Field(name) // Get a *Field based on the given field namef, ok:=s.FieldOk(name) // Get a *Field based on the given field namen:=s.Name() // Get the struct nameh:=s.HasZero() // Check if any field is uninitializedz:=s.IsZero() // Check if all fields are uninitializedWe can easily examine a single Field for more detail. Below you can see how we get and interact with various field methods:
s:=structs.New(server)
// Get the Field struct for the "Name" fieldname:=s.Field("Name")
// Get the underlying value, value => "gopher"value:=name.Value().(string)
// Set the field's valuename.Set("another gopher")
// Get the field's kind, kind => "string"name.Kind()
// Check if the field is exported or notifname.IsExported() {
fmt.Println("Name field is exported")
}
// Check if the value is a zero value, such as "" for string, 0 for intif!name.IsZero() {
fmt.Println("Name is initialized")
}
// Check if the field is an anonymous (embedded) fieldif!name.IsEmbedded() {
fmt.Println("Name is not an embedded field")
}
// Get the Field's tag value for tag name "json", tag value => "name,omitempty"tagValue:=name.Tag("json")Nested structs are supported too:
addrField:=s.Field("Server").Field("Addr")
// Get the value for addra:=addrField.Value().(string)
// Or get all fieldshttpServer:=s.Field("Server").Fields()We can also get a slice of Fields from the Struct type to iterate over all fields. This is handy if you wish to examine all fields:
s:=structs.New(server)
for_, f:=ranges.Fields() {
fmt.Printf("field name: %+v\n", f.Name())
iff.IsExported() {
fmt.Printf("value : %+v\n", f.Value())
fmt.Printf("is zero : %+v\n", f.IsZero())
}
}The MIT License (MIT) - see LICENSE.md for more details