package reflections

Import Path
	github.com/oleiade/reflections (on go.dev)

Dependency Relation
	imports 3 packages, and imported by one package

Involved Source Files Package reflections provides high level abstractions over the Go standard [reflect] library. In practice, the `reflect` library's API proves somewhat low-level and un-intuitive. Using it can turn out pretty complex, daunting, and scary, when doing simple things like accessing a structure field value, a field tag, etc. The `reflections` package aims to make developers' life easier when it comes to introspect struct values at runtime. Its API takes inspiration in the python language's `getattr,` `setattr,` and `hasattr` set of methods and provides simplified access to structure fields and tags.
Code Examples package main import ( "fmt" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } var fields []string // Fields will list every structure exportable fields. // Here, it's content would be equal to: // []string{"FirstField", "SecondField", "ThirdField"} fields, _ = reflections.Fields(s) fmt.Println(fields) } package main import ( "fmt" "log" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } fieldsToExtract := []string{"FirstField", "ThirdField"} for _, fieldName := range fieldsToExtract { value, err := reflections.GetField(s, fieldName) if err != nil { log.Fatal(err) } fmt.Println(value) } } package main import ( "fmt" "log" "reflect" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } var firstFieldKind reflect.Kind var secondFieldKind reflect.Kind var err error // GetFieldKind will return reflect.String firstFieldKind, err = reflections.GetFieldKind(s, "FirstField") if err != nil { log.Fatal(err) } fmt.Println(firstFieldKind) // GetFieldKind will return reflect.Int secondFieldKind, err = reflections.GetFieldKind(s, "SecondField") if err != nil { log.Fatal(err) } fmt.Println(secondFieldKind) } package main import ( "encoding/json" "fmt" "log" "github.com/oleiade/reflections" ) func main() { type Order struct { Step string `json:"order_step"` ID string `json:"id"` Category string `json:"category"` } type Condition struct { Field string `json:"field"` Value string `json:"value"` Next string `json:"next"` } // JSON data from external source orderJSON := `{ "order_step": "cooking", "id": "45457-fv54f54", "category": "Pizzas" }` conditionJSON := `{ "field": "order_step", "value": "cooking", "next": "serve" }` // Storing JSON in corresponding Variables var order Order err := json.Unmarshal([]byte(orderJSON), &order) if err != nil { log.Fatal(err) } var condition Condition err = json.Unmarshal([]byte(conditionJSON), &condition) if err != nil { log.Fatal(err) } fieldName, _ := reflections.GetFieldNameByTagValue(order, "json", condition.Field) fmt.Println(fieldName) fieldValue, _ := reflections.GetField(order, fieldName) fmt.Println(fieldValue) } package main import ( "fmt" "log" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{} tag, err := reflections.GetFieldTag(s, "FirstField", "matched") if err != nil { log.Fatal(err) } fmt.Println(tag) tag, err = reflections.GetFieldTag(s, "ThirdField", "unmatched") if err != nil { log.Fatal(err) } fmt.Println(tag) } package main import ( "fmt" "log" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } var firstFieldType string var secondFieldType string var err error // GetFieldType will return reflect.String firstFieldType, err = reflections.GetFieldType(s, "FirstField") if err != nil { log.Fatal(err) } fmt.Println(firstFieldType) // GetFieldType will return reflect.Int secondFieldType, err = reflections.GetFieldType(s, "SecondField") if err != nil { log.Fatal(err) } fmt.Println(secondFieldType) } package main import ( "fmt" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } // has == true has, _ := reflections.HasField(s, "FirstField") fmt.Println(has) // has == false has, _ = reflections.HasField(s, "FourthField") fmt.Println(has) } package main import ( "fmt" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } var structItems map[string]interface{} // Items will return a field name to // field value map structItems, _ = reflections.Items(s) fmt.Println(structItems) } package main import ( "fmt" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", MyEmbeddedStruct: MyEmbeddedStruct{ EmbeddedField: "embedded value", }, } var structItems map[string]interface{} // ItemsDeep will return a field name to // field value map, including fields from // anonymous embedded structs structItems, _ = reflections.ItemsDeep(s) fmt.Println(structItems) } package main import ( "log" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } // In order to be able to set the structure's values, // a pointer to it has to be passed to it. err := reflections.SetField(&s, "FirstField", "new value") if err != nil { log.Fatal(err) } // Note that if you try to set a field's value using the wrong type, // an error will be returned _ = reflections.SetField(&s, "FirstField", 123) // err != nil } package main import ( "fmt" "github.com/oleiade/reflections" ) type MyStruct struct { MyEmbeddedStruct FirstField string `matched:"first tag"` SecondField int `matched:"second tag"` ThirdField string `unmatched:"third tag"` } type MyEmbeddedStruct struct { EmbeddedField string } func main() { s := MyStruct{ FirstField: "first value", SecondField: 2, ThirdField: "third value", } var structTags map[string]string // Tags will return a field name to tag content // map. Nota that only field with the tag name // you've provided which will be matched. // Here structTags will contain: // { // "FirstField": "first tag", // "SecondField": "second tag", // } structTags, _ = reflections.Tags(s, "matched") fmt.Println(structTags) }
Package-Level Functions (total 13)
Fields returns the struct fields names list. The `obj` parameter can either be a structure or pointer to structure.
FieldsDeep returns "flattened" fields. Note that FieldsDeep treats fields from anonymous inner structs as normal fields.
GetField returns the value of the provided obj field. The `obj` can either be a structure or pointer to structure.
GetFieldKind returns the kind of the provided obj field. The `obj` can either be a structure or pointer to structure.
GetFieldNameByTagValue looks up a field with a matching `{tagKey}:"{tagValue}"` tag in the provided `obj` item. The `obj` parameter must be a `struct`, or a `pointer` to one. If the `obj` parameter doesn't have a field tagged with the `tagKey`, and the matching `tagValue`, this function returns an error.
GetFieldTag returns the provided obj field tag value. The `obj` parameter can either be a structure or pointer to structure.
GetFieldType returns the kind of the provided obj field. The `obj` can either be a structure or pointer to structure.
HasField checks if the provided `obj` struct has field named `name`. The `obj` can either be a structure or pointer to structure.
Items returns the field:value struct pairs as a map. The `obj` parameter can either be a structure or pointer to structure.
ItemsDeep returns "flattened" items. Note that ItemsDeep will treat fields from anonymous inner structs as normal fields.
SetField sets the provided obj field with provided value. The `obj` parameter must be a pointer to a struct, otherwise it soundly fails. The provided `value` type should match with the struct field being set.
Tags lists the struct tag fields. The `obj` can whether be a structure or pointer to structure.
TagsDeep returns "flattened" tags. Note that TagsDeep treats fields from anonymous inner structs as normal fields.
Package-Level Variables (total 2)
ErrUnexportedField indicates that an operation failed as a result of applying to a non-exported struct field.
ErrUnsupportedType indicates that the provided type doesn't support the requested reflection operation.