github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/g/Struct_README.md (about)

     1  
     2  # Struct
     3  
     4  Struct contains various utilities to work with Go (Golang) g. It was
     5  initially used by me to convert a struct into a `map[string]interface{}`. With
     6  time I've added other utilities for g.  It's basically a high level
     7  package based on primitives from the reflect package. Feel free to add new
     8  functions or improve the existing code.
     9  
    10  ## Install
    11  
    12  ```bash
    13  go get github.com/angenalZZZ/gofunc/g
    14  ```
    15  
    16  ## Usage and Examples
    17  
    18  Just like the standard lib `strings`, `bytes` and co packages, `struct` has
    19  many global functions to manipulate or organize your struct data. Lets define
    20  and declare a struct:
    21  
    22  ```go
    23  type Server struct {
    24  	Name        string `json:"name,omitempty"`
    25  	ID          int
    26  	Enabled     bool
    27  	users       []string // not exported
    28  	http.Server          // embedded
    29  }
    30  
    31  server := &Server{
    32  	Name:    "gopher",
    33  	ID:      123456,
    34  	Enabled: true,
    35  }
    36  ```
    37  
    38  ```go
    39  // Convert a struct to a map[string]interface{}
    40  // => {"Name":"gopher", "ID":123456, "Enabled":true}
    41  m := g.Maps(server)
    42  
    43  // Convert the values of a struct to a []interface{}
    44  // => ["gopher", 123456, true]
    45  v := g.Values(server)
    46  
    47  // Convert the names of a struct to a []string
    48  // (see "Names methods" for more info about fields)
    49  n := g.Names(server)
    50  
    51  // Convert the values of a struct to a []*Field
    52  // (see "Field methods" for more info about fields)
    53  f := g.Fields(server)
    54  
    55  // Return the struct name => "Server"
    56  n := g.Name(server)
    57  
    58  // Check if any field of a struct is initialized or not.
    59  h := g.HasZero(server)
    60  
    61  // Check if all fields of a struct is initialized or not.
    62  z := g.IsZero(server)
    63  
    64  // Check if server is a struct or a pointer to struct
    65  i := g.IsStruct(server)
    66  ```
    67  
    68  ### Struct methods
    69  
    70  The struct functions can be also used as independent methods by creating a new
    71  `*g.Struct`. This is handy if you want to have more control over the
    72  struct (such as retrieving a single Field).
    73  
    74  ```go
    75  // Create a new struct type:
    76  s := g.NewStruct(server)
    77  
    78  m := s.Maps()              // Get a map[string]interface{}
    79  v := s.Values()           // Get a []interface{}
    80  f := s.Fields()           // Get a []*Field
    81  n := s.Names()            // Get a []string
    82  f := s.Field(name)        // Get a *Field based on the given field name
    83  f, ok := s.FieldOk(name)  // Get a *Field based on the given field name
    84  n := s.Name()             // Get the struct name
    85  h := s.HasZero()          // Check if any field is uninitialized
    86  z := s.IsZero()           // Check if all fields are uninitialized
    87  ```
    88  
    89  ### Field methods
    90  
    91  We can easily examine a single Field for more detail. Below you can see how we
    92  get and interact with various field methods:
    93  
    94  
    95  ```go
    96  s := g.NewStruct(server)
    97  
    98  // Get the Field struct for the "Name" field
    99  name := s.Field("Name")
   100  
   101  // Get the underlying value,  value => "gopher"
   102  value := name.Value().(string)
   103  
   104  // Set the field's value
   105  name.Set("another gopher")
   106  
   107  // Get the field's kind, kind =>  "string"
   108  name.Kind()
   109  
   110  // Check if the field is exported or not
   111  if name.IsExported() {
   112  	fmt.Println("Name field is exported")
   113  }
   114  
   115  // Check if the value is a zero value, such as "" for string, 0 for int
   116  if !name.IsZero() {
   117  	fmt.Println("Name is initialized")
   118  }
   119  
   120  // Check if the field is an anonymous (embedded) field
   121  if !name.IsEmbedded() {
   122  	fmt.Println("Name is not an embedded field")
   123  }
   124  
   125  // Get the Field's tag value for tag name "json", tag value => "name,omitempty"
   126  tagValue := name.Tag("json")
   127  ```
   128  
   129  Nested struct are supported too:
   130  
   131  ```go
   132  addrField := s.Field("Server").Field("Addr")
   133  
   134  // Get the value for addr
   135  a := addrField.Value().(string)
   136  
   137  // Or get all fields
   138  httpServer := s.Field("Server").Fields()
   139  ```
   140  
   141  We can also get a slice of Fields from the Struct type to iterate over all
   142  fields. This is handy if you wish to examine all fields:
   143  
   144  ```go
   145  s := g.NewStruct(server)
   146  
   147  for _, f := range s.Fields() {
   148  	fmt.Printf("field name: %+v\n", f.Name())
   149  
   150  	if f.IsExported() {
   151  		fmt.Printf("value   : %+v\n", f.Value())
   152  		fmt.Printf("is zero : %+v\n", f.IsZero())
   153  	}
   154  }
   155  ```