Because not all types are comparable, e.g. a slice. So we can\'t do this
var v ArbitraryType
v == reflect.Zero(reflect.TypeOf(v)).Interface()
Both of the following give me reasonable results (probably because they're the same?)
reflect.ValueOf(v) == reflect.Zero(reflect.TypeOf(v)))
reflect.DeepEqual(reflect.ValueOf(v), reflect.Zero(reflect.TypeOf(v)))
e.g. various integer 0 flavours and uninitialized struct
s are "zero"
Sadly, empty strings and arrays are not. and nil
gives an exception.
You could special case these if you wanted.
As Peter Noyes points out, you just need to make sure you're not comparing a type which isn't comparable. Luckily, this is very straightforward with the reflect
package:
func IsZero(v interface{}) (bool, error) {
t := reflect.TypeOf(v)
if !t.Comparable() {
return false, fmt.Errorf("type is not comparable: %v", t)
}
return v == reflect.Zero(t).Interface(), nil
}
See an example use here.
Go 1.13 introduced Value.IsZero
method in reflect
package. This is how you can check for zero value using it:
if reflect.ValueOf(v).IsZero() {
// v is zero, do something
}
Apart from basic types, it also works for Chan, Func, Array, Interface, Map, Ptr, Slice, UnsafePointer, and Struct.
See this post:
Golang: Reflection - How to get zero value of a field type
Basically you need to have special cases for the non comparable types.