empty_value.go 1008 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. //go:build !go1.18
  2. // +build !go1.18
  3. package missinggo
  4. import "reflect"
  5. func IsZeroValue(i interface{}) bool {
  6. return IsEmptyValue(reflect.ValueOf(i))
  7. }
  8. // Returns whether the value represents the empty value for its type. Used for
  9. // example to determine if complex types satisfy the common "omitempty" tag
  10. // option for marshalling. Taken from
  11. // http://stackoverflow.com/a/23555352/149482.
  12. func IsEmptyValue(v reflect.Value) bool {
  13. switch v.Kind() {
  14. case reflect.Func, reflect.Map, reflect.Slice:
  15. return v.IsNil()
  16. case reflect.Array:
  17. z := true
  18. for i := 0; i < v.Len(); i++ {
  19. z = z && IsEmptyValue(v.Index(i))
  20. }
  21. return z
  22. case reflect.Struct:
  23. z := true
  24. vType := v.Type()
  25. for i := 0; i < v.NumField(); i++ {
  26. // ignore unexported fields to avoid reflection panics
  27. if !vType.Field(i).IsExported() {
  28. continue
  29. }
  30. z = z && IsEmptyValue(v.Field(i))
  31. }
  32. return z
  33. }
  34. // Compare other types directly:
  35. z := reflect.Zero(v.Type())
  36. return v.Interface() == z.Interface()
  37. }