Skip to content

Commit

Permalink
Add GetType
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfmin committed Aug 29, 2019
1 parent 4959e02 commit c120117
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 36 deletions.
69 changes: 33 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,6 @@ go get github.com/sunfmin/reflectutils




* [Variables](#variables)
* [Get](#get)
* [Must Get](#must-get)
* [Set](#set)


## Variables
``` go
var NoSuchFieldError = errors.New("no such field.")
```


## Get
``` go
func Get(i interface{}, name string) (value interface{}, err error)
```
Get value of a struct by path using reflect.



## Must Get
``` go
func MustGet(i interface{}, name string) (value interface{})
```
MustGet get value of a struct by path using reflect, return nil if anything in the path is nil



## Set
``` go
func Set(i interface{}, name string, value interface{}) (err error)
```
Set value of a struct by path using reflect.


By given these structs
```go
type Person struct {
Expand Down Expand Up @@ -355,6 +319,39 @@ If you set a property that don't exists, it gives you an error.
// no such field.
```

Get Type of a deep nested object
```go
type Variant struct {
Name string
}
type Product struct {
Variants []*Variant
ByCode map[string]*Variant
}
type Obj struct {
MainProduct *Product
}

var o *Obj

fmt.Println(GetType(o, "MainProduct.Variants[0].Name"))
fmt.Println(GetType(o, "MainProduct.Variants[0]"))
fmt.Println(GetType(o, "MainProduct.Variants"))
fmt.Println(GetType(o, "MainProduct"))
fmt.Println(GetType(o, "MainProduct.ByCode.abc"))
fmt.Println(GetType(o, "MainProduct.ByCode"))
fmt.Println(GetType(o, "x123.ByCode"))
fmt.Println(GetType(o, "MainProduct.ByCode.abc.NotExist"))
//Output:
//string
//*reflectutils_test.Variant
//[]*reflectutils_test.Variant
//*reflectutils_test.Product
//*reflectutils_test.Variant
//map[string]*reflectutils_test.Variant
//<nil>
//<nil>
```



35 changes: 35 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,41 @@ func ExampleSet_7notexists() {
// no such field.
}


// Get Type of a deep nested object
func ExampleSet_8gettype() {
type Variant struct {
Name string
}
type Product struct {
Variants []*Variant
ByCode map[string]*Variant
}
type Obj struct {
MainProduct *Product
}

var o *Obj

fmt.Println(GetType(o, "MainProduct.Variants[0].Name"))
fmt.Println(GetType(o, "MainProduct.Variants[0]"))
fmt.Println(GetType(o, "MainProduct.Variants"))
fmt.Println(GetType(o, "MainProduct"))
fmt.Println(GetType(o, "MainProduct.ByCode.abc"))
fmt.Println(GetType(o, "MainProduct.ByCode"))
fmt.Println(GetType(o, "x123.ByCode"))
fmt.Println(GetType(o, "MainProduct.ByCode.abc.NotExist"))
//Output:
//string
//*reflectutils_test.Variant
//[]*reflectutils_test.Variant
//*reflectutils_test.Product
//*reflectutils_test.Variant
//map[string]*reflectutils_test.Variant
//<nil>
//<nil>
}

func printJsonV(v interface{}) {
j, _ := json.MarshalIndent(v, "", "\t")
fmt.Printf("\n\n%s\n", j)
Expand Down
52 changes: 52 additions & 0 deletions get_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package reflectutils

import (
"reflect"
"strings"
)

// Get value of a struct by path using reflect.
func GetType(i interface{}, name string) (t reflect.Type) {
var err error

t = reflect.TypeOf(i)

if name == "" {
return
}

var token *dotToken
token, err = nextDot(name)
if err != nil {
return nil
}

if t.Kind() == reflect.Map || t.Kind() == reflect.Slice {
t = GetType(reflect.Zero(t.Elem()).Interface(), token.Left)
return
}

if t.Kind() != reflect.Struct {
for t.Elem().Kind() == reflect.Ptr {
t = t.Elem()
}

t = t.Elem()
}

if t.Kind() == reflect.Struct {

sf, ok := t.FieldByNameFunc(func(name string) bool {
return strings.EqualFold(name, token.Field)
})

if !ok {
return nil
}

t = GetType(reflect.Zero(sf.Type).Interface(), token.Left)
return
}

return
}

0 comments on commit c120117

Please sign in to comment.