funk.Get can't handle struct fields with interface{} type
radaiming opened this issue · comments
Hello,
When trying following codes:
package main
import (
"github.com/davecgh/go-spew/spew"
"github.com/thoas/go-funk"
)
type Foo struct {
Sth interface{}
}
type User struct {
Phone struct {
CountryCode string
Number int
}
Age int
}
func main() {
e := Foo{
Sth: User{
Phone: struct {
CountryCode string
Number int
}{CountryCode: "+1", Number: 123},
Age: 10,
},
}
spew.Dump(funk.Get(e, "Sth.Age"))
spew.Dump(funk.Get(e, "Sth.Phone.Number"))
spew.Dump(funk.Get(e, "Sth.Phone.CountryCode"))
}
What I expect to get is:
(int) 10
(int) 123
(string) (len=2) "+1"
But actually I get 3 repeated
(main.User) {
Phone: (struct { CountryCode string; Number int }) {
CountryCode: (string) (len=2) "+1",
Number: (int) 123
},
Age: (int) 10
}
The reason looks like, Foo.Sth is interface type and redirectValue doesn't handle this, I try to fix it with this change:
- if !value.IsValid() || value.Kind() != reflect.Ptr {
+ if !value.IsValid() || (value.Kind() != reflect.Ptr && value.Kind() != reflect.Interface) {
return value
}
- res := reflect.Indirect(value)
+ res := value.Elem()
It works and all tests pass, but not sure if other things will be broken. If the change do work correctly, could you please apply it(or me send a PR)? Thanks.
hi @radaiming,
You can send directly a PR for this and it will be tested by the CI.