reflect: reflect.Value.IsZero
lukescott opened this issue ยท 17 comments
Many encoding packages have a custom internal "isEmptyValue" function. The
functionality is pretty much identical. This expands to other packages that use reflect,
such as an ORM (is primary key set?).
It would be useful to have a standard "IsZero" method on reflect.Value,
something like this (copied from encoding/xml):
func (v Value) IsZero() bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return false
}I believe this is correct:
func (v Value) IsZero() bool {
switch v.Kind() {
case reflect.Array, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
return v.IsNil()
}
return false
}
it seems a reasonable feature request.
Labels changed: added release-go1.4, repo-main.
Status changed to Accepted.
r's suggested revision still slightly deviates from the language defined notion of a type's zero value. Arrays and structs are zero if all their members have respective zero values. Yes, zero-size types (such as with the above array length check) are guaranteed to be their own zero value, but that's not a particularly common scenario. Zero length slices and maps would only be zero if they're also nil.
Perhaps there could be an "IsZero" and "IsEmpty" method. "IsEmpty" would be the same as "IsZero", but also include zero length slices and maps. Including structs would be nice, although the current omitempty implementations in encoding/* don't. However, that doesn't mean those implementations have to use "IsEmpty" for Go 1. Third party / internal encoding libraries may choose to use the method though, which still makes it useful to implement.
It's not clear to me what would use IsZero if we added it.
It's easy for packages to define what they really want themselves.
I'm wary of continuing to add to reflect.
I don't want it to be a kitchen sink of helpers.
Not arguing for or against, just a datapoint on intuitiveness: I found this page while looking for a reflect.IsZero that would actually test for zero values of structs.
reflect.IsZero(x) feels like it should return true for any y in var x y, to me.
But this is moot if it's not added.
Postponing to Go 1.7 (Go1.6Maybe was a misclick), along with discussion of omitzero in xml and json.
CL https://golang.org/cl/23064 mentions this issue.
Any updates on this topic? This should be a reasonable feature request.
I'll turn this into a proposal for consideration.
Note that thereโs also discussion of an internal runtime.isZero for optimized codegen:
#23929
Change https://golang.org/cl/171337 mentions this issue: reflect: implement Value.IsZero()
So, this will be available in Go 1.13?