-
-
Notifications
You must be signed in to change notification settings - Fork 529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't panic with 'omitempty' and uncomparable type #361
Conversation
i think use Value.IsZero is better..😊 |
You mean checking if the struct has the |
reflect.Value.IsZero() can use check struct fields all zero value. than not need use Comparable() to check.. |
I had to go back and look why I didn't use it @kkHAIKE, but the problem is that it considers e.g. Example program: package main
import (
"fmt"
"reflect"
)
func main() {
type Strukt struct{ Slice []int }
a := reflect.ValueOf(Strukt{Slice: []int{1}})
b := reflect.ValueOf(Strukt{Slice: []int{}})
c := reflect.ValueOf(Strukt{})
fmt.Printf("%-10s %-8s %s\n", "", "isZero", "isEmpty")
fmt.Printf("%-10s %-8v %v\n", "values", a.IsZero(), isEmpty(a))
fmt.Printf("%-10s %-8v %v\n", "[]int{}", b.IsZero(), isEmpty(b))
fmt.Printf("%-10s %-8v %v\n", "no value", c.IsZero(), isEmpty(c))
}
func isEmpty(rv reflect.Value) bool {
switch rv.Kind() {
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
return rv.Len() == 0
case reflect.Struct:
if rv.Type().Comparable() {
return reflect.Zero(rv.Type()).Interface() == rv.Interface()
}
// Not comparable; need to loop over all fields and call isEmpty()
// recursively so that we check the length for slices etc.
for i := 0; i < rv.NumField(); i++ {
if isEmpty(rv.Field(i)) {
return true
}
}
case reflect.Bool:
return !rv.Bool()
}
return false
} Outputs:
|
oh.. sorry, i forgot this case...change the impl to that i think Array always not be length 0 func isEmpty(rv reflect.Value) bool {
switch rv.Kind() {
case Array:
for i := 0; i < v.Len(); i++ {
if !isEmpty(rv.Index(i)) {
return false
}
}
return true
case reflect.Slice, reflect.Map:
return rv.Len() == 0
case reflect.Struct:
for i := 0; i < rv.NumField(); i++ {
if !isEmpty(rv.Field(i)) {
return false
}
}
return true
}
return rv.IsZero()
} |
Cheers, thanks; I mentioned the discussion in #360; might be a few weeks before I look at this, but happy to accept PRs as long as they add decent test cases! |
Fixes #360