NotNil(fi, t)
}
+func TestIsZero(t *testing.T) {
+ for i, tt := range []struct {
+ x interface{}
+ want bool
+ }{
+ // Booleans
+ {true, false},
+ {false, true},
+ // Numeric types
+ {int(0), true},
+ {int(1), false},
+ {int8(0), true},
+ {int8(1), false},
+ {int16(0), true},
+ {int16(1), false},
+ {int32(0), true},
+ {int32(1), false},
+ {int64(0), true},
+ {int64(1), false},
+ {uint(0), true},
+ {uint(1), false},
+ {uint8(0), true},
+ {uint8(1), false},
+ {uint16(0), true},
+ {uint16(1), false},
+ {uint32(0), true},
+ {uint32(1), false},
+ {uint64(0), true},
+ {uint64(1), false},
+ {float32(0), true},
+ {float32(1.2), false},
+ {float64(0), true},
+ {float64(1.2), false},
+ {math.Copysign(0, -1), false},
+ {complex64(0), true},
+ {complex64(1.2), false},
+ {complex128(0), true},
+ {complex128(1.2), false},
+ {complex(math.Copysign(0, -1), 0), false},
+ {complex(0, math.Copysign(0, -1)), false},
+ {complex(math.Copysign(0, -1), math.Copysign(0, -1)), false},
+ {uintptr(0), true},
+ {uintptr(128), false},
+ // Array
+ {Zero(TypeOf([5]string{})).Interface(), true},
+ {[5]string{"", "", "", "", ""}, true},
+ {[5]string{}, true},
+ {[5]string{"", "", "", "a", ""}, false},
+ // Chan
+ {(chan string)(nil), true},
+ {make(chan string), false},
+ {time.After(1), false},
+ // Func
+ {(func())(nil), true},
+ {New, false},
+ // Interface
+ {New(TypeOf(new(error)).Elem()).Elem(), true},
+ {(io.Reader)(strings.NewReader("")), false},
+ // Map
+ {(map[string]string)(nil), true},
+ {map[string]string{}, false},
+ {make(map[string]string), false},
+ // Ptr
+ {(*func())(nil), true},
+ {(*int)(nil), true},
+ {new(int), false},
+ // Slice
+ {[]string{}, false},
+ {([]string)(nil), true},
+ {make([]string, 0), false},
+ // Strings
+ {"", true},
+ {"not-zero", false},
+ // Structs
+ {T{}, true},
+ {T{123, 456.75, "hello", &_i}, false},
+ // UnsafePointer
+ {(unsafe.Pointer)(nil), true},
+ {(unsafe.Pointer)(new(int)), false},
+ } {
+ var x Value
+ if v, ok := tt.x.(Value); ok {
+ x = v
+ } else {
+ x = ValueOf(tt.x)
+ }
+
+ b := x.IsZero()
+ if b != tt.want {
+ t.Errorf("%d: IsZero((%s)(%+v)) = %t, want %t", i, x.Kind(), tt.x, b, tt.want)
+ }
+
+ if !Zero(TypeOf(tt.x)).IsZero() {
+ t.Errorf("%d: IsZero(Zero(TypeOf((%s)(%+v)))) is false", i, x.Kind(), tt.x)
+ }
+ }
+
+ func() {
+ defer func() {
+ if r := recover(); r == nil {
+ t.Error("should panic for invalid value")
+ }
+ }()
+ (Value{}).IsZero()
+ }()
+}
+
func TestInterfaceExtraction(t *testing.T) {
var s struct {
W io.Writer
return v.flag != 0
}
+// IsZero reports whether v is a zero value for its type.
+// It panics if the argument is invalid.
+func (v Value) IsZero() bool {
+ switch v.kind() {
+ case Bool:
+ return !v.Bool()
+ case Int, Int8, Int16, Int32, Int64:
+ return v.Int() == 0
+ case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return v.Uint() == 0
+ case Float32, Float64:
+ return math.Float64bits(v.Float()) == 0
+ case Complex64, Complex128:
+ c := v.Complex()
+ return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
+ case Array:
+ for i := 0; i < v.Len(); i++ {
+ if !v.Index(i).IsZero() {
+ return false
+ }
+ }
+ return true
+ case Chan, Func, Interface, Map, Ptr, Slice, UnsafePointer:
+ return v.IsNil()
+ case String:
+ return v.Len() == 0
+ case Struct:
+ for i := 0; i < v.NumField(); i++ {
+ if !v.Field(i).IsZero() {
+ return false
+ }
+ }
+ return true
+ default:
+ // This should never happens, but will act as a safeguard for
+ // later, as a default value doesn't makes sense here.
+ panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
+ }
+}
+
// Kind returns v's Kind.
// If v is the zero Value (IsValid returns false), Kind returns Invalid.
func (v Value) Kind() Kind {