Documentation ¶
Overview ¶
Package reflect extends the standard reflect package.
Index ¶
- func DoEqual(x, y interface{}) (err error)
- func IsEqual(x, y interface{}) bool
- func IsNil(v interface{}) bool
- func Marshal(obj interface{}) (out []byte, err error, ok bool)
- func Set(obj reflect.Value, val string) (err error)
- func Tag(field reflect.StructField, tag string) (val string, opts []string, hasTag bool)
- func Unmarshal(obj reflect.Value, val []byte) (ok bool, err error)
- type Equaler
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DoEqual ¶ added in v0.21.0
func DoEqual(x, y interface{}) (err error)
DoEqual is a naive interfaces comparison that check and use Equaler interface and return an error if its not match.
func IsEqual ¶
func IsEqual(x, y interface{}) bool
IsEqual is a naive interfaces comparison that check and use Equaler interface.
func IsNil ¶
func IsNil(v interface{}) bool
IsNil will return true if v's type is chan, func, interface, map, pointer, or slice and its value is `nil`; otherwise it will return false.
Example ¶
var ( aBoolean bool aChannel chan int aFunction F aMap map[int]int aPtr *T aSlice []int anInt int emptyError error fs http.FileSystem ) cases := []struct { v interface{} }{ {}, // Uninitialized interface{}. {v: aBoolean}, {v: aChannel}, // Uninitialized channel. {v: aFunction}, // Empty func type. {v: aMap}, // Uninitialized map. {v: make(map[int]int)}, // Initialized map. {v: aPtr}, // Uninitialized pointer to struct. {v: &T{}}, // Initialized pointer to struct. {v: aSlice}, // Uninitialized slice. {v: make([]int, 0)}, // Initialized slice. {v: anInt}, {v: emptyError}, {v: errors.New("e")}, // Initialized error. {v: fs}, // Uninitialized interface type to interface{}. } for _, c := range cases { fmt.Printf("%19T: v == nil is %5t, IsNil() is %5t\n", c.v, c.v == nil, IsNil(c.v)) }
Output: <nil>: v == nil is true, IsNil() is true bool: v == nil is false, IsNil() is false chan int: v == nil is false, IsNil() is true reflect.F: v == nil is false, IsNil() is true map[int]int: v == nil is false, IsNil() is true map[int]int: v == nil is false, IsNil() is false *reflect.T: v == nil is false, IsNil() is true *reflect.T: v == nil is false, IsNil() is false []int: v == nil is false, IsNil() is true []int: v == nil is false, IsNil() is false int: v == nil is false, IsNil() is false <nil>: v == nil is true, IsNil() is true *errors.errorString: v == nil is false, IsNil() is false <nil>: v == nil is true, IsNil() is true
func Marshal ¶ added in v0.39.0
Marshal marshal the obj value to []byte by calling one of the method: MarshalBinary, MarshalJSON, or MarshalText; in respective order.
If obj implement one of the method with valid signature, it will return (out, nil, true); unless there is an error.
If the method signature invalid it will return (nil, err, false).
If obj is nil or none of the method exist it will return (nil, nil, false).
Example ¶
var ( vint = 1 vUrl, _ = url.Parse("https://example.org") bigRat = big.NewRat(100, 2) bigInt = big.NewInt(50) imt = &InvalidMarshalText{} emj = &ErrorMarshalJson{} out []byte err error ok bool ) out, err, ok = Marshal(vint) fmt.Println(out, err, ok) out, err, ok = Marshal(&vint) fmt.Println(out, err, ok) out, err, ok = Marshal(vUrl) fmt.Println(string(out), err, ok) out, err, ok = Marshal(bigRat) fmt.Println(string(out), err, ok) out, err, ok = Marshal(bigInt) fmt.Println(string(out), err, ok) out, err, ok = Marshal(imt) fmt.Println(string(out), err, ok) out, err, ok = Marshal(emj) fmt.Println(string(out), err, ok)
Output: [] <nil> false [] <nil> false https://example.org <nil> true 50 <nil> true 50 <nil> true Marshal: expecting first return as []byte got string false Marshal: ErrorMarshalJson: test true
func Set ¶ added in v0.39.0
Set the obj value by converting the string val to the obj type.
If the obj type is an interface or struct, its value will be set by calling Unmarshal function.
It will return an error if,
- obj is not setable, variable is passed without pointer or pointer not initialized.
- val is overflow
- obj Kind is Invalid, Array, Chan, Func, Map, or UnsafePointer.
Example (Bool) ¶
type Bool bool var ( err error vbool bool mybool Bool ) err = Set(reflect.ValueOf(&vbool), "YES") if err != nil { fmt.Println("error:", err) } else { fmt.Println("YES:", vbool) } err = Set(reflect.ValueOf(&vbool), "TRUE") if err != nil { fmt.Println("error:", err) } else { fmt.Println("TRUE:", vbool) } err = Set(reflect.ValueOf(&vbool), "False") if err != nil { fmt.Println("error:", err) } else { fmt.Println("False:", vbool) } err = Set(reflect.ValueOf(&vbool), "1") if err != nil { fmt.Println("error:", err) } else { fmt.Println("1:", vbool) } err = Set(reflect.ValueOf(&mybool), "true") if err != nil { fmt.Println("error:", err) } else { fmt.Println("true:", mybool) }
Output: YES: true TRUE: true False: false 1: true true: true
Example (Float) ¶
type myFloat float32 var ( vf32 float32 myfloat myFloat err error ) err = Set(reflect.ValueOf(&vf32), "1.223") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vf32) } err = Set(reflect.ValueOf(&myfloat), "999.999") if err != nil { fmt.Println("error:", err) } else { fmt.Println(myfloat) }
Output: 1.223 999.999
Example (Int) ¶
type myInt int var ( vint int vint8 int8 vint16 int16 vmyint myInt err error ) err = Set(reflect.ValueOf(&vint), "") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vint) } err = Set(reflect.ValueOf(&vint), "1") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vint) } err = Set(reflect.ValueOf(&vint8), "-128") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vint8) } // Value of int16 is overflow. err = Set(reflect.ValueOf(&vint16), "32768") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vint16) } err = Set(reflect.ValueOf(&vmyint), "32768") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vmyint) }
Output: 0 1 -128 error: Set: int16 value is overflow: 32768 32768
Example (SliceByte) ¶
type myBytes []byte var ( vbytes []byte vmyBytes myBytes err error ) err = Set(reflect.ValueOf(vbytes), "Show me") if err != nil { fmt.Println("error:", err) } else { fmt.Println(string(vbytes)) } err = Set(reflect.ValueOf(&vbytes), "a hero") if err != nil { fmt.Println("error:", err) } else { fmt.Println(string(vbytes)) } err = Set(reflect.ValueOf(&vbytes), "") if err != nil { fmt.Println("error:", err) } else { fmt.Println(string(vbytes)) } err = Set(reflect.ValueOf(&vmyBytes), "and I will write you a tragedy") if err != nil { fmt.Println("error:", err) } else { fmt.Println(string(vmyBytes)) }
Output: error: Set: object []uint8 is not setable a hero and I will write you a tragedy
Example (SliceString) ¶
var ( vstring []string err error ) err = Set(reflect.ValueOf(vstring), "Show me") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vstring) } err = Set(reflect.ValueOf(&vstring), "a hero") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vstring) } err = Set(reflect.ValueOf(&vstring), "and I will write you a tragedy") if err != nil { fmt.Println("error:", err) } else { fmt.Println(vstring) }
Output: error: Set: object []string is not setable [a hero] [a hero and I will write you a tragedy]
Example (Unmarshal) ¶
var ( rat = big.NewRat(0, 1) myUrl = &url.URL{} bigInt = big.NewInt(1) err error ) // This Set will call UnmarshalText on big.Rat. err = Set(reflect.ValueOf(rat), "1.234") if err != nil { fmt.Println("error:", err) } else { fmt.Println(rat.FloatString(4)) } err = Set(reflect.ValueOf(rat), "") if err != nil { fmt.Println("error:", err) } else { fmt.Println(rat.FloatString(4)) } // This Set will call UnmarshalBinary on url.URL. err = Set(reflect.ValueOf(myUrl), "https://kilabit.info") if err != nil { fmt.Println("error:", err) } else { fmt.Println(myUrl) } // This Set will call UnmarshalJSON. err = Set(reflect.ValueOf(bigInt), "123_456") if err != nil { fmt.Println("error:", err) } else { fmt.Println(bigInt) } err = Set(reflect.ValueOf(bigInt), "") if err != nil { fmt.Println("error:", err) } else { fmt.Println(bigInt) }
Output: 1.2340 0.0000 https://kilabit.info 123456 0
func Tag ¶ added in v0.39.0
Tag simplify lookup on struct's field tag.
Given a StructField and the name of tag, return the tag's value and options inside the tag. The options is any string after tag's value, separated by comma. For example, given the following field definition
F `tag:"name,opt1, opt2"`
It will return (name, [opt1 opt2], true).
If the field is exported but does not have tag, it will return the field name (as is without converting to lower case) in val with hasTag is false: (Name, nil, false).
If the field is unexported or tag is "-" it will return empty val with hasTag is false ("", nil, false).
Example ¶
type T struct { F1 int `atag:" f1 , opt1 , opt2 ,"` F2 int `atag:", opt1"` F3 int F4 int `atag:" - ,opt1"` } var ( t T vtype reflect.Type field reflect.StructField val string opts []string x int hasTag bool ) vtype = reflect.TypeOf(t) for x = 0; x < vtype.NumField(); x++ { field = vtype.Field(x) val, opts, hasTag = Tag(field, "atag") fmt.Println(val, opts, hasTag) }
Output: f1 [opt1 opt2 ] true F2 [opt1] false F3 [] false [] false
func Unmarshal ¶ added in v0.39.0
Unmarshal set the obj value by calling one of the method: UnmarshalBinary, UnmarshalJSON, or UnmarshalText; in respective order.
Just like reflect, the obj value must be pointer to initialized variable (&T) or pointer-to-pointer to uninitialized variable (**T).
If obj implement one of the method, it will return (true, nil) if there is no error.
If none of the method exist on obj, it will return (false, nil).
Example (UnmarshalBinary) ¶
var ( val = []byte("https://kilabit.info") err error ok bool ) // Passing variable will not work... var varB url.URL ok, err = Unmarshal(reflect.ValueOf(varB), val) if err != nil { fmt.Println(err) return } fmt.Println(varB.String(), ok) // Pass it like these. ok, err = Unmarshal(reflect.ValueOf(&varB), val) if err != nil { fmt.Println(err) return } fmt.Println(varB.String(), ok) // Passing un-initialized pointer also not working... var varPtrB *url.URL ok, err = Unmarshal(reflect.ValueOf(varPtrB), val) if err != nil { fmt.Println(err) return } fmt.Println(varPtrB, ok) // Pass it as **T. ok, err = Unmarshal(reflect.ValueOf(&varPtrB), val) if err != nil { fmt.Println(err) return } fmt.Println(varPtrB, ok) var ptrB = &url.URL{} ok, err = Unmarshal(reflect.ValueOf(&ptrB), val) if err != nil { fmt.Println(err) return } fmt.Println(ptrB, ok)
Output: false https://kilabit.info true <nil> false https://kilabit.info true https://kilabit.info true
Example (UnmarshalJSON) ¶
var ( vals = [][]byte{ []byte("123.456"), []byte("123_456"), []byte("123456"), } bigInt = big.NewInt(1) val []byte err error ) for _, val = range vals { _, err = Unmarshal(reflect.ValueOf(bigInt), val) if err != nil { fmt.Println(err) } else { fmt.Println(bigInt) } }
Output: Unmarshal: math/big: cannot unmarshal "123.456" into a *big.Int 123456 123456
Example (UnmarshalText) ¶
var ( vals = [][]byte{ []byte(""), []byte("123.456"), []byte("123_456"), []byte("123456"), } r = big.NewRat(0, 1) val []byte err error ) for _, val = range vals { _, err = Unmarshal(reflect.ValueOf(r), val) if err != nil { fmt.Println(err) } else { fmt.Println(r) } }
Output: 0/1 15432/125 123456/1 123456/1