Documentation ¶
Overview ¶
Package ref provides the higher level wraps on golang reflect library.
Example (Array) ¶
Dump([1]interface{}{3}, "x", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "x" ([1]interface {}): x[0].type = int x[0].value = 3
Example (Equal) ¶
//!+ fmt.Println(Equal([]int{1, 2, 3}, []int{1, 2, 3})) // "true" fmt.Println(Equal([]string{"foo"}, []string{"bar"})) // "false" fmt.Println(Equal([]string(nil), []string{})) // "true" fmt.Println(Equal(map[string]int(nil), map[string]int{})) // "true" //!-
Output: true false true true
Example (EqualCycle) ¶
//!+cycle // Circular linked lists a -> b -> a and c -> c. type link struct { value string tail *link } a, b, c := &link{value: "a"}, &link{value: "b"}, &link{value: "c"} a.tail, b.tail, c.tail = b, a, c fmt.Println(Equal(a, a)) // "true" fmt.Println(Equal(b, b)) // "true" fmt.Println(Equal(c, c)) // "true" fmt.Println(Equal(a, b)) // "false" fmt.Println(Equal(a, c)) // "false" //!-cycle
Output: true true true false false
Example (Expr) ¶
e, _ := eval.Parse("sqrt(A / pi)") Dump(e, "e", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "e" (eval.call): e.fn = "sqrt" e.args[0].type = eval.binary e.args[0].value.op = 47 e.args[0].value.x.type = eval.Var e.args[0].value.x.value = "A" e.args[0].value.y.type = eval.Var e.args[0].value.y.value = "pi"
Example (Interface) ¶
var i interface{} = 3 Dump(i, "i", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "i" (int): i = 3
Example (Movie) ¶
//!+movie type Movie struct { Title, Subtitle string Year int Color bool Actor map[string]string Oscars []string Sequel *string } //!-movie //!+strangelove strangelove := Movie{ Title: "Dr. Strangelove", Subtitle: "How I Learned to Stop Worrying and Love the Bomb", Year: 1964, Color: false, Actor: map[string]string{ "Dr. Strangelove": "Peter Sellers", "Grp. Capt. Lionel Mandrake": "Peter Sellers", "Pres. Merkin Muffley": "Peter Sellers", "Gen. Buck Turgidson": "George C. Scott", "Brig. Gen. Jack D. Ripper": "Sterling Hayden", `Maj. T.J. "King" Kong`: "Slim Pickens", }, Oscars: []string{ "Best Actor (Nomin.)", "Best Adapted Screenplay (Nomin.)", "Best Director (Nomin.)", "Best Picture (Nomin.)", }, } //!-strangelove Dump(strangelove, "strangelove", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) }) // We don't use an Output: comment since displaying // a map is nondeterministic. /* //!+output Display strangelove (display.Movie): strangelove.Title = "Dr. Strangelove" strangelove.Subtitle = "How I Learned to Stop Worrying and Love the Bomb" strangelove.Year = 1964 strangelove.Color = false strangelove.Actor["Gen. Buck Turgidson"] = "George C. Scott" strangelove.Actor["Brig. Gen. Jack D. Ripper"] = "Sterling Hayden" strangelove.Actor["Maj. T.J. \"King\" Kong"] = "Slim Pickens" strangelove.Actor["Dr. Strangelove"] = "Peter Sellers" strangelove.Actor["Grp. Capt. Lionel Mandrake"] = "Peter Sellers" strangelove.Actor["Pres. Merkin Muffley"] = "Peter Sellers" strangelove.Oscars[0] = "Best Actor (Nomin.)" strangelove.Oscars[1] = "Best Adapted Screenplay (Nomin.)" strangelove.Oscars[2] = "Best Director (Nomin.)" strangelove.Oscars[3] = "Best Picture (Nomin.)" strangelove.Sequel = nil //!-output */
Output:
Example (NilInterface) ¶
var w io.Writer Dump(w, "w", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "w" (<nil>): w = <invalid>
Example (PtrToInterface) ¶
var w io.Writer Dump(&w, "&w", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "&w" (*io.Writer): (*&w) = nil
Example (PtrToInterface2) ¶
var i interface{} = 3 Dump(&i, "&i", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "&i" (*interface {}): (*&i).type = int (*&i).value = 3
Example (Slice) ¶
Dump([]*int{new(int), nil}, "slice", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "slice" ([]*int): (*slice[0]) = 0 slice[1] = nil
Example (Struct) ¶
Dump(struct{ x interface{} }{3}, "x", func(level int, desc string, v reflect.Value) { fmt.Println(strings.Repeat(" ", level+1), desc) })
Output: Dumping "x" (struct { x interface {} }): x.x.type = int x.x.value = 3
Index ¶
- Constants
- Variables
- func Any(value interface{}) string
- func CanIsNil(v reflect.Value) bool
- func CanIsZero(v reflect.Value) bool
- func Captalize(s string) string
- func Clone(fromVar, toVar interface{}, opts ...CloneOpt) interface{}
- func Dump(obj interface{}, objDesc string, ...)
- func DumpEx(obj interface{}, objDesc string, ...)
- func Equal(x, y interface{}) bool
- func Fields(obj interface{}) ([]string, error)
- func FieldsDeep(obj interface{}) ([]string, error)
- func FieldsDeeper(obj interface{}, ...) error
- func FieldsTagDeeper(obj interface{}, tagKey string, ...) error
- func GetField(obj interface{}, fieldName string) (field interface{}, err error)
- func GetFieldKind(obj interface{}, fieldName string) (kind reflect.Kind, err error)
- func GetFieldKinds(obj interface{}, fieldNames ...string) (kinds []reflect.Kind, err error)
- func GetFieldTag(obj interface{}, tagKey string, fieldName string) (tagValue string, err error)
- func GetFieldTags(obj interface{}, tagKey string, fieldNames ...string) (tagValues []string, err error)
- func GetFieldType(obj interface{}, fieldName string) (typ string, err error)
- func GetFieldTypes(obj interface{}, fieldNames ...string) (types []string, err error)
- func GetFields(obj interface{}, fieldNames ...string) (fields []interface{}, err error)
- func GetUnexportedField(field reflect.Value) interface{}
- func HasAnyField(obj interface{}, names ...string) (has bool)
- func HasField(obj interface{}, name string) (has bool)
- func IndirectType(reflectType reflect.Type) reflect.Type
- func IndirectTypeRecursive(reflectType reflect.Type) reflect.Type
- func IndirectValue(reflectValue reflect.Value) reflect.Value
- func IndirectValueRecursive(reflectValue reflect.Value) reflect.Value
- func IsNil(v reflect.Value) bool
- func IsNilSafe(v reflect.Value) bool
- func IsZero(v reflect.Value) bool
- func IsZeroSafe(v reflect.Value) bool
- func Items(obj interface{}) (map[string]interface{}, error)
- func ItemsDeep(obj interface{}) (map[string]interface{}, error)
- func SetField(obj interface{}, name string, value interface{}) (err error)
- func SetNil(to reflect.Value)
- func SetUnexportedField(field reflect.Value, value interface{})
- func SetZero(to reflect.Value)
- func Tags(obj interface{}, key string) (map[string]string, error)
- func TagsDeep(obj interface{}, key string) (map[string]string, error)
- func TryConvert(v reflect.Value, t reflect.Type) (out reflect.Value, err error)
- type CloneOpt
- func WithEachFieldAlways(b bool) CloneOpt
- func WithIgnoreUnexportedError(ignored bool) CloneOpt
- func WithIgnoredFieldNames(names ...string) CloneOpt
- func WithKeepIfFromIsNilOrZero(keepIfFromIsNil, keepIfFromIsZero bool) CloneOpt
- func WithNameMappings(m map[string]string) CloneOpt
- func WithNameMappingsRule(rule NameMappingRule) CloneOpt
- func WithZeroIfEqualsFrom(b bool) CloneOpt
- type Cloneable
- type Cloner
- type Field
- type Merger
- type NameMappingRule
- type Opt
- type Type
- type Value
- func (v Value) GetValue() (val interface{})
- func (v Value) IndirectType() Type
- func (v Value) IndirectTypeRecursive() Type
- func (v Value) IndirectValue() Value
- func (v Value) IndirectValueRecursive() Value
- func (v Value) IsComplex() bool
- func (v Value) IsFloat() bool
- func (v Value) IsInt() bool
- func (v Value) IsKindComplex(k reflect.Kind) bool
- func (v Value) IsKindFloat(k reflect.Kind) bool
- func (v Value) IsKindInt(k reflect.Kind) bool
- func (v Value) IsKindInteger(k reflect.Kind) bool
- func (v Value) IsKindPointer(k reflect.Kind) bool
- func (v Value) IsKindStruct(k reflect.Kind) bool
- func (v Value) IsKindUint(k reflect.Kind) bool
- func (v Value) IsNil() bool
- func (v Value) IsPointer() bool
- func (v Value) IsString() bool
- func (v Value) IsStruct() bool
- func (v Value) IsZero() bool
- func (v Value) PtrToIndirectValueRecursive() Value
- func (v Value) SetNil()
- func (v Value) SetZero()
- func (v Value) TryConvert(t reflect.Type) (out reflect.Value, err error)
- Bugs
Examples ¶
- Package (Array)
- Package (Equal)
- Package (EqualCycle)
- Package (Expr)
- Package (Interface)
- Package (Movie)
- Package (NilInterface)
- Package (PtrToInterface)
- Package (PtrToInterface2)
- Package (Slice)
- Package (Struct)
- Fields
- GetField
- GetFieldKind
- GetFieldTag
- GetFieldType
- HasField
- Items
- ItemsDeep
- SetField
- Tags
Constants ¶
const ( // AppName const AppName = "ref" // Version const Version = "0.3.1" // VersionInt const VersionInt = 0x000301 )
Variables ¶
var ( DefaultNameMappingRule NameMappingRule = func(fromName string) (toName string, mapped bool) { return } DefaultCloner = buildDefaultCloner() LazyGobCopier = lazyCopier{} )
Functions ¶
func Captalize ¶
Captalize returns a copy of the string s with all Unicode letters that begin words mapped to their Unicode title case.
BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
func Clone ¶
func Clone(fromVar, toVar interface{}, opts ...CloneOpt) interface{}
Clone makes a deep clone of 'from'.
Note that toVar should be a pointer to a struct while you're cloning on a struct, for example:
var u1 = User{Name:"aa"} var u2 = new(User) fmt.Println(ref.Clone(u1, u2))
Clone will make the cloned object from fromVar with Cloneable interface. It's talking about the better way to clone an object is implement the Cloneable interface.
For the normally object cloning, Clone uses Golang reflect feature. So we can only clone the exported fields of a struct in this case. The unexported fields will be ignored by default ( see also cloner.IgnoreUnexportedError ) .
func DumpEx ¶
func DumpEx(obj interface{}, objDesc string, dumper func(level int, desc string, v reflect.Value), preDumper, postDumper func(v reflect.Value))
DumpEx prints the structure and value of an object with pretty format
func Equal ¶
func Equal(x, y interface{}) bool
!+comparison Equal reports whether x and y are deeply equal. !-comparison
Map keys are always compared with ==, not deeply. (This matters for keys containing pointers or interfaces.) !+comparison
func Fields ¶
Fields returns the struct fields names list. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" ) 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, _ = ref.Fields(s) fmt.Println(fields) }
Output:
func FieldsDeep ¶
FieldsDeep returns "flattened" fields (fields from anonymous inner structs are treated as normal fields)
func FieldsDeeper ¶
func FieldsDeeper(obj interface{}, fn func(owner *reflect.Value, thisField reflect.StructField, this reflect.Value)) error
FieldsDeeper returns "flattened" fields (fields from anonymous inner structs are treated as normal fields)
func FieldsTagDeeper ¶
func FieldsTagDeeper(obj interface{}, tagKey string, fn func(owner *reflect.Value, thisField reflect.StructField, this reflect.Value, tagValue string)) error
FieldsTagDeeper returns "flattened" fields (fields from anonymous inner structs are treated as normal fields)
func GetField ¶
GetField returns the value of the provided obj field. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" "log" ) 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 := ref.GetField(s, fieldName) if err != nil { log.Fatal(err) } fmt.Println(value) } }
Output:
func GetFieldKind ¶
GetFieldKind returns the kind of the provided obj field. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" "log" "reflect" ) 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 = ref.GetFieldKind(s, "FirstField") if err != nil { log.Fatal(err) } fmt.Println(firstFieldKind) // GetFieldKind will return reflect.Int secondFieldKind, err = ref.GetFieldKind(s, "SecondField") if err != nil { log.Fatal(err) } fmt.Println(secondFieldKind) }
Output:
func GetFieldKinds ¶
GetFieldKind returns the kind of the provided obj field. obj can whether be a structure or pointer to structure.
func GetFieldTag ¶
GetFieldTag returns the provided obj field tag value. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" "log" ) 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 := ref.GetFieldTag(s, "matched", "FirstField") if err != nil { log.Fatal(err) } fmt.Println(tag) tag, err = ref.GetFieldTag(s, "unmatched", "ThirdField") if err != nil { log.Fatal(err) } fmt.Println(tag) }
Output:
func GetFieldTags ¶
func GetFieldTags(obj interface{}, tagKey string, fieldNames ...string) (tagValues []string, err error)
GetFieldTag returns the provided obj field tag value. obj can whether be a structure or pointer to structure.
func GetFieldType ¶
GetFieldType returns the kind of the provided obj field. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" "log" ) 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 = ref.GetFieldType(s, "FirstField") if err != nil { log.Fatal(err) } fmt.Println(firstFieldType) // GetFieldType will return reflect.Int secondFieldType, err = ref.GetFieldType(s, "SecondField") if err != nil { log.Fatal(err) } fmt.Println(secondFieldType) }
Output:
func GetFieldTypes ¶
GetFieldType returns the kind of the provided obj field. obj can whether be a structure or pointer to structure.
func GetFields ¶
GetFields returns the value of the provided obj field. obj can whether be a structure or pointer to structure.
func GetUnexportedField ¶
func HasAnyField ¶
HasAnyField checks the existences of the given name list
func HasField ¶
HasField checks if the provided field name is part of a struct. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" ) 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 := ref.HasField(s, "FirstField") fmt.Println(has) // has == false has = ref.HasField(s, "FourthField") fmt.Println(has) }
Output:
func IsNil ¶
IsNil reports whether its argument v is nil. The argument must be a chan, func, interface, map, pointer, or slice value; if it is not, IsNil panics. Note that IsNil is not always equivalent to a regular comparison with nil in Go. For example, if v was created by calling ValueOf with an uninitialized interface variable i, i==nil will be true but v.IsNil will panic as v will be the zero Value.
func IsNilSafe ¶
IsNilSafe reports whether its argument v is nil. The argument must be a chan, func, interface, map, pointer, or slice value; if it is not, IsNil panics. Note that IsNil is not always equivalent to a regular comparison with nil in Go. For example, if v was created by calling ValueOf with an uninitialized interface variable i, i==nil will be true but v.IsNil will panic as v will be the zero Value.
func IsZero ¶
IsZero reports whether v is the zero value for its type. It panics if the argument is invalid.
func IsZeroSafe ¶
IsZeroSafe reports whether v is the zero value for its type. It panics if the argument is invalid.
func Items ¶
Items returns the field - value struct pairs as a map. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" ) 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, _ = ref.Items(s) fmt.Println(structItems) }
Output:
func ItemsDeep ¶
FieldsDeep returns "flattened" items (fields from anonymous inner structs are treated as normal fields)
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" ) 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, _ = ref.ItemsDeep(s) fmt.Println(structItems) }
Output:
func SetField ¶
SetField sets the provided obj field with provided value. obj param has to be a pointer to a struct, otherwise it will soundly fail. Provided value type should match with the struct field you're trying to set.
Example ¶
package main import ( "github.com/hedzr/ref" "log" ) 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 := ref.SetField(&s, "FirstField", "new value") if err != nil { log.Fatal(err) } // If you try to set a field's value using the wrong type, // an error will be returned err = ref.SetField(&s, "FirstField", 123) // err != nil if err != nil { log.Fatal(err) } }
Output:
func SetUnexportedField ¶
func Tags ¶
Tags lists the struct tag fields. obj can whether be a structure or pointer to structure.
Example ¶
package main import ( "fmt" "github.com/hedzr/ref" ) 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, _ = ref.Tags(s, "matched") fmt.Println(structTags) }
Output:
Types ¶
type CloneOpt ¶
type CloneOpt func(c *cloner)
CloneOpt is functional option functor for Clone()
func WithEachFieldAlways ¶
func WithIgnoredFieldNames ¶
WithIgnoredFieldNames appends the ignored name list to the Cloner operator.
func WithNameMappings ¶
func WithNameMappingsRule ¶
func WithNameMappingsRule(rule NameMappingRule) CloneOpt
func WithZeroIfEqualsFrom ¶
type Cloneable ¶
type Cloneable interface {
// Clone will always return a new cloned object instance on 'this' object
Clone() interface{}
}
Cloneable interface represents a cloneable object
type Field ¶
type Field struct { Type reflect.StructField Value reflect.Value }
func (Field) GetUnexportedField ¶
func (field Field) GetUnexportedField() interface{}
func (Field) SetUnexportedField ¶
func (field Field) SetUnexportedField(value interface{})
type Merger ¶
type Merger struct { IgnoreUnexportedError bool // contains filtered or unexported fields }
type NameMappingRule ¶
type Type ¶
Type is a struct wrapped on reflect.Type
func TypeOf ¶
func TypeOf(obj interface{}) Type
TypeOf returns the reflection Type that represents the dynamic type of i. If i is a nil interface value, TypeOf returns nil.
func (Type) IndirectType ¶
func (Type) IndirectTypeRecursive ¶
type Value ¶
Value is a struct wrapped on reflect.Value
func ValueOf ¶
func ValueOf(obj interface{}) Value
ValueOf is a copy of reflect.ValueOf(i) but wrapped as ref.Value
both the original object and its reflect.Value obj can be passed into ValueOf.
import "github.com/hedzr/assert" import "github.com/hedzr/ref" import "reflect" a := &User{Name:"me"} va := reflect.ValueOf(a) vv1 := ref.ValueOf(a) vv2 := ref.ValueOf(va) assert.Equal(t, vv1, vv2) // vv1 and vv2 should be always equivalent.
func (Value) IndirectType ¶
func (Value) IndirectTypeRecursive ¶
func (Value) IndirectValue ¶
func (Value) IndirectValueRecursive ¶
func (Value) IsZero ¶
IsZero reports whether v is the zero value for its type. It panics if the argument is invalid.
func (Value) PtrToIndirectValueRecursive ¶
Notes ¶
Bugs ¶
The rule Title uses for word boundaries does not handle Unicode punctuation properly.
The rule Title uses for word boundaries does not handle Unicode punctuation properly.