func checkAgainstComplex64(e complex64, c reflect.Value) (err error) { err = errors.New("") realPart := real(e) imaginaryPart := imag(e) switch { case isInteger(c) || isFloat(c): // If we have no imaginary part, then we should just compare against the // real part. Otherwise, we can't be equal. if imaginaryPart != 0 { return } return checkAgainstFloat32(realPart, c) case isComplex(c): // Compare using complex64 to avoid a false sense of precision; otherwise // e.g. Equals(0.1 + 0i) won't match float32(0.1). if complex64(c.Complex()) == e { err = nil } default: err = NewFatalError("which is not numeric") } return }
func checkAgainstComplex128(e complex128, c reflect.Value) (err error) { err = errors.New("") realPart := real(e) imaginaryPart := imag(e) switch { case isInteger(c) || isFloat(c): // If we have no imaginary part, then we should just compare against the // real part. Otherwise, we can't be equal. if imaginaryPart != 0 { return } return checkAgainstFloat64(realPart, c) case isComplex(c): if c.Complex() == e { err = nil } default: err = NewFatalError("which is not numeric") } return }
func nonzero(v reflect.Value) bool { switch v.Kind() { 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.Complex64, reflect.Complex128: return v.Complex() != complex(0, 0) case reflect.String: return v.String() != "" case reflect.Struct: for i := 0; i < v.NumField(); i++ { if nonzero(getField(v, i)) { return true } } return false case reflect.Array: for i := 0; i < v.Len(); i++ { if nonzero(v.Index(i)) { return true } } return false case reflect.Map, reflect.Interface, reflect.Slice, reflect.Ptr, reflect.Chan, reflect.Func: return !v.IsNil() case reflect.UnsafePointer: return v.Pointer() != 0 } return true }
func builtinImag(cplx reflect.Value) reflect.Value { if cplx.Type() == c128 { return reflect.ValueOf(float64(imag(cplx.Complex()))) } else { return reflect.ValueOf(float32(imag(cplx.Complex()))) } }
func encodeBasic(v reflect.Value) string { t := v.Type() switch k := t.Kind(); k { case reflect.Bool: return strconv.FormatBool(v.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return strconv.FormatInt(v.Int(), 10) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return strconv.FormatUint(v.Uint(), 10) case reflect.Float32: return strconv.FormatFloat(v.Float(), 'g', -1, 32) case reflect.Float64: return strconv.FormatFloat(v.Float(), 'g', -1, 64) case reflect.Complex64, reflect.Complex128: s := fmt.Sprintf("%g", v.Complex()) return strings.TrimSuffix(strings.TrimPrefix(s, "("), ")") case reflect.String: return v.String() } panic(t.String() + " has unsupported kind " + t.Kind().String()) }
// Returns the string representation of the field value func (enc *encoder) encodeCol(fv reflect.Value, st reflect.StructTag) string { switch fv.Kind() { case reflect.String: return fv.String() case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8: return fmt.Sprintf("%v", fv.Int()) case reflect.Float32: return encodeFloat(32, fv) case reflect.Float64: return encodeFloat(64, fv) case reflect.Bool: return encodeBool(fv.Bool(), st) case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8: return fmt.Sprintf("%v", fv.Uint()) case reflect.Complex64, reflect.Complex128: return fmt.Sprintf("%+.3g", fv.Complex()) case reflect.Interface: return encodeInterface(fv, st) case reflect.Struct: return encodeInterface(fv, st) default: panic(fmt.Sprintf("Unsupported type %s", fv.Kind())) } return "" }
func evalBinaryComplexExpr(x reflect.Value, op token.Token, y reflect.Value) (reflect.Value, error) { var r complex128 var is_bool bool var b bool xx, yy := x.Complex(), y.Complex() switch op { case token.ADD: r = xx + yy case token.SUB: r = xx - yy case token.MUL: r = xx * yy case token.QUO: if yy == 0 { return reflect.Value{}, PanicDivideByZero{} } r = xx / yy case token.EQL: b = xx == yy is_bool = true case token.NEQ: b = xx != yy is_bool = true default: panic(dytc("bad binary op")) } if is_bool { return reflect.ValueOf(b), nil } else { return reflect.ValueOf(r).Convert(x.Type()), nil } }
// isZero reports whether the value is the zero of its type. func isZero(val reflect.Value) bool { switch val.Kind() { case reflect.Array: for i := 0; i < val.Len(); i++ { if !isZero(val.Index(i)) { return false } } return true case reflect.Map, reflect.Slice, reflect.String: return val.Len() == 0 case reflect.Bool: return !val.Bool() case reflect.Complex64, reflect.Complex128: return val.Complex() == 0 case reflect.Chan, reflect.Func, reflect.Ptr: return val.IsNil() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return val.Int() == 0 case reflect.Float32, reflect.Float64: return val.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return val.Uint() == 0 case reflect.Struct: for i := 0; i < val.NumField(); i++ { if !isZero(val.Field(i)) { return false } } return true } panic("unknown type in isZero " + val.Type().String()) }
func formatValue(value reflect.Value, indentation uint) string { if indentation > MaxDepth { return "..." } if isNilValue(value) { return "nil" } if UseStringerRepresentation { if value.CanInterface() { obj := value.Interface() switch x := obj.(type) { case fmt.GoStringer: return x.GoString() case fmt.Stringer: return x.String() } } } switch value.Kind() { case reflect.Bool: return fmt.Sprintf("%v", value.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return fmt.Sprintf("%v", value.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return fmt.Sprintf("%v", value.Uint()) case reflect.Uintptr: return fmt.Sprintf("0x%x", value.Uint()) case reflect.Float32, reflect.Float64: return fmt.Sprintf("%v", value.Float()) case reflect.Complex64, reflect.Complex128: return fmt.Sprintf("%v", value.Complex()) case reflect.Chan: return fmt.Sprintf("0x%x", value.Pointer()) case reflect.Func: return fmt.Sprintf("0x%x", value.Pointer()) case reflect.Ptr: return formatValue(value.Elem(), indentation) case reflect.Slice: return formatSlice(value, indentation) case reflect.String: return formatString(value.String(), indentation) case reflect.Array: return formatSlice(value, indentation) case reflect.Map: return formatMap(value, indentation) case reflect.Struct: return formatStruct(value, indentation) case reflect.Interface: return formatValue(value.Elem(), indentation) default: if value.CanInterface() { return fmt.Sprintf("%#v", value.Interface()) } else { return fmt.Sprintf("%#v", value) } } }
func isZeroValue(v reflect.Value) bool { switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return 0 == v.Int() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return 0 == v.Uint() case reflect.String: return "" == v.String() case reflect.Bool: return !v.Bool() case reflect.Float32, reflect.Float64: return 0 == v.Float() case reflect.Complex64, reflect.Complex128: return 0 == real(v.Complex()) && 0 == imag(v.Complex()) } return false }
// isTrue reports whether the value is 'true', in the sense of not the zero of its type, // and whether the value has a meaningful truth value. func isTrue(val reflect.Value) (truth, ok bool) { if !val.IsValid() { // Something like var x interface{}, never set. It's a form of nil. return false, true } switch val.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: truth = val.Len() > 0 case reflect.Bool: truth = val.Bool() case reflect.Complex64, reflect.Complex128: truth = val.Complex() != 0 case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: truth = !val.IsNil() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: truth = val.Int() != 0 case reflect.Float32, reflect.Float64: truth = val.Float() != 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: truth = val.Uint() != 0 case reflect.Struct: truth = true // Struct values are always true. default: return } return truth, true }
func reflectValue(f *reflect.StructField, v reflect.Value) *Ident { ident := new(Ident) // Evaluate primitive types. switch f.Type.Kind() { case reflect.String: ident.Name = v.String() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: ident.Name = fmt.Sprint(v.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: ident.Name = fmt.Sprint(v.Uint()) case reflect.Float32, reflect.Float64: ident.Name = fmt.Sprint(v.Float()) case reflect.Bool: ident.Name = fmt.Sprint(v.Bool()) case reflect.Complex64, reflect.Complex128: ident.Name = fmt.Sprint(v.Complex()) case reflect.Struct: // Check for interface and custom types. switch x := v.Interface().(type) { case Identifier: ident = x.Ident() case time.Time: ident.Name = chrono.Format(x) case fmt.Stringer: ident.Name = x.String() } case reflect.Interface, reflect.Ptr: if v.IsNil() { return nil } // Check for interface and custom types. switch x := v.Interface().(type) { case Identifier: ident = x.Ident() case time.Time: ident.Name = chrono.Format(x) case fmt.Stringer: ident.Name = x.String() } default: logrus.Debugf("origins: skipping unsupported field %s (%s type)", f.Name, f.Type.Kind()) return nil } return ident }
func refToVal(ref reflect.Value) Value { switch ref.Kind() { case reflect.Bool: return boolValue(ref.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return intValue(ref.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return intValue(ref.Uint()) case reflect.Float32, reflect.Float64: return floatValue(ref.Float()) case reflect.Complex64, reflect.Complex128: return complexValue(ref.Complex()) case reflect.Array, reflect.Slice: return arrayValue{reflectValue(ref)} case reflect.Chan: return chanValue{reflectValue(ref)} case reflect.Map: return mapValue{reflectValue(ref)} case reflect.Ptr: return pointerValue{reflectValue(ref)} case reflect.String: return stringValue(ref.String()) case reflect.Struct: return structValue{reflectValue(ref)} } return nilValue(0) }
func complex64Encoder(enc *encoder, v reflect.Value) error { bs := enc.buf[:8] x := v.Complex() enc.order.PutUint32(bs, math.Float32bits(float32(real(x)))) enc.order.PutUint32(bs[4:], math.Float32bits(float32(imag(x)))) _, err := enc.Write(bs) return err }
func putReflect(b []byte, v reflect.Value) int { v = reflect.Indirect(v) switch v.Kind() { case reflect.String: s := v.String() PutString(b, s) return len(s) + 1 case reflect.Bool: PutBool(b, v.Bool()) return 1 case reflect.Int: PutInt(b, int(v.Int())) return 8 case reflect.Uint: PutUint(b, uint(v.Uint())) return 8 case reflect.Int8: PutInt8(b, int8(v.Int())) case reflect.Uint8: PutUint8(b, uint8(v.Uint())) case reflect.Int16: PutInt16(b, int16(v.Int())) case reflect.Uint16: PutUint16(b, uint16(v.Uint())) case reflect.Int32: PutInt32(b, int32(v.Int())) case reflect.Uint32: PutUint32(b, uint32(v.Uint())) case reflect.Int64: PutInt64(b, v.Int()) case reflect.Uint64: PutUint64(b, v.Uint()) case reflect.Float32: PutFloat32(b, float32(v.Float())) case reflect.Float64: PutFloat64(b, v.Float()) case reflect.Complex64: PutComplex64(b, complex64(v.Complex())) case reflect.Complex128: PutComplex128(b, v.Complex()) case reflect.Struct: sum := 0 for i, n := 0, v.NumField(); i < n; i++ { s := putReflect(b[sum:], v.Field(i)) if s < 0 { return -1 } sum += s } if sum == 0 { return -1 } return sum default: return -1 } return int(v.Type().Size()) }
// encComplex encodes the complex value (complex64 complex128) referenced by v. // Complex numbers are just a pair of floating-point numbers, real part first. func encComplex(i *encInstr, state *encoderState, v reflect.Value) { c := v.Complex() if c != 0+0i || state.sendZero { rpart := floatBits(real(c)) ipart := floatBits(imag(c)) state.update(i) state.encodeUint(rpart) state.encodeUint(ipart) } }
func snapvalue(w io.Writer, v reflect.Value) { var q string switch v.Kind() { case reflect.Bool: // Not addressable q = strconv.FormatBool(v.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: q = strconv.FormatInt(v.Int(), 36) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: q = strconv.FormatUint(v.Uint(), 36) case reflect.Uintptr: panic("n/s") case reflect.Float32, reflect.Float64: q = strconv.FormatFloat(v.Float(), 'g', 65, 64) case reflect.Complex64, reflect.Complex128: c := v.Complex() q = "(" + strconv.FormatFloat(real(c), 'g', 65, 64) + ", " + strconv.FormatFloat(imag(c), 'g', 65, 64) + "i)" case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: // Addressable q = strconv.FormatUint(uint64(v.Pointer()), 36) // uintptr case reflect.Interface: d := v.InterfaceData() // [2]uintptr q = "<" + strconv.FormatUint(uint64(d[0]), 36) + "," + strconv.FormatUint(uint64(d[1]), 36) + ">" case reflect.String: q = v.String() case reflect.Array: w.Write([]byte("{")) for i := 0; i < v.Len(); i++ { snapvalue(w, v.Index(i)) w.Write([]byte(",")) } w.Write([]byte("}")) return case reflect.Struct: w.Write([]byte("{")) for i := 0; i < v.NumField(); i++ { snapvalue(w, v.FieldByIndex([]int{i})) w.Write([]byte(",")) } w.Write([]byte("}")) default: panic("u") } w.Write([]byte(q)) }
func complex128Encoder(enc *encoder, v reflect.Value) error { bs := enc.buf[:8] x := v.Complex() enc.order.PutUint64(bs, math.Float64bits(real(x))) if _, err := enc.Write(bs); err != nil { return err } enc.order.PutUint64(bs, math.Float64bits(imag(x))) _, err := enc.Write(bs) return err }
func AsBool(value reflect.Value) bool { if !value.IsValid() { return false } switch value.Kind() { case reflect.Int: fallthrough case reflect.Int16: fallthrough case reflect.Int32: fallthrough case reflect.Int64: return value.Int() != 0 case reflect.Uint: fallthrough case reflect.Uint16: fallthrough case reflect.Uint32: fallthrough case reflect.Uint64: return value.Uint() != 0 case reflect.Float32: fallthrough case reflect.Float64: return value.Float() != 0.0 case reflect.Complex64: fallthrough case reflect.Complex128: return value.Complex() != complex128(0) case reflect.Bool: return value.Bool() case reflect.String: fallthrough case reflect.Map: fallthrough case reflect.Array: fallthrough case reflect.Slice: return value.Len() != 0 case reflect.Ptr: if value.Elem().Kind() != reflect.Struct { return false } fallthrough case reflect.Struct: return true case reflect.Func: return true } log.Println("Not Support kind=" + value.Kind().String()) return false }
func formatValue(value reflect.Value, indentation uint) string { if indentation > maxIndent { return "Too deep for me, man..." } if isNilValue(value) { return "nil" } switch value.Kind() { case reflect.Bool: return fmt.Sprintf("%v", value.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return fmt.Sprintf("%v", value.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return fmt.Sprintf("%v", value.Uint()) case reflect.Uintptr: return fmt.Sprintf("0x%x", value.Uint()) case reflect.Float32, reflect.Float64: return fmt.Sprintf("%v", value.Float()) case reflect.Complex64, reflect.Complex128: return fmt.Sprintf("%v", value.Complex()) case reflect.Chan: return fmt.Sprintf("0x%x", value.Pointer()) case reflect.Func: return fmt.Sprintf("0x%x", value.Pointer()) case reflect.Ptr: return formatValue(value.Elem(), indentation) case reflect.Slice: if value.Type().Elem().Kind() == reflect.Uint8 { return formatString(value.Bytes(), indentation) } return formatSlice(value, indentation) case reflect.String: return formatString(value.String(), indentation) case reflect.Array: return formatSlice(value, indentation) case reflect.Map: return formatMap(value, indentation) case reflect.Struct: return formatStruct(value, indentation) case reflect.Interface: return formatValue(value.Elem(), indentation) default: if value.CanInterface() { return fmt.Sprintf("%#v", value.Interface()) } else { return fmt.Sprintf("%#v", value) } } }
// keyEqual compares a and b for equality. // Both a and b must be valid map keys. func keyEqual(av, bv reflect.Value) bool { if !av.IsValid() && !bv.IsValid() { return true } if !av.IsValid() || !bv.IsValid() || av.Type() != bv.Type() { return false } switch kind := av.Kind(); kind { case reflect.Bool: a, b := av.Bool(), bv.Bool() return a == b case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: a, b := av.Int(), bv.Int() return a == b case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: a, b := av.Uint(), bv.Uint() return a == b case reflect.Float32, reflect.Float64: a, b := av.Float(), bv.Float() return a == b case reflect.Complex64, reflect.Complex128: a, b := av.Complex(), bv.Complex() return a == b case reflect.Array: for i := 0; i < av.Len(); i++ { if !keyEqual(av.Index(i), bv.Index(i)) { return false } } return true case reflect.Chan, reflect.UnsafePointer, reflect.Ptr: a, b := av.Pointer(), bv.Pointer() return a == b case reflect.Interface: return keyEqual(av.Elem(), bv.Elem()) case reflect.String: a, b := av.String(), bv.String() return a == b case reflect.Struct: for i := 0; i < av.NumField(); i++ { if !keyEqual(av.Field(i), bv.Field(i)) { return false } } return true default: panic("invalid map key type " + av.Type().String()) } }
func evalUnaryComplexExpr(ctx *Ctx, x reflect.Value, op token.Token) (reflect.Value, error) { var err error var r complex128 xx := x.Complex() switch op { case token.ADD: r = +xx case token.SUB: r = -xx default: panic("eval: impossible unary op " + op.String()) } return reflect.ValueOf(r).Convert(x.Type()), err }
func (mw *Writer) writeVal(v reflect.Value) error { if !isSupported(v.Kind()) { return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type()) } // shortcut for nil values if v.IsNil() { return mw.WriteNil() } switch v.Kind() { case reflect.Bool: return mw.WriteBool(v.Bool()) case reflect.Float32, reflect.Float64: return mw.WriteFloat64(v.Float()) case reflect.Complex64, reflect.Complex128: return mw.WriteComplex128(v.Complex()) case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8: return mw.WriteInt64(v.Int()) case reflect.Interface, reflect.Ptr: if v.IsNil() { mw.WriteNil() } return mw.writeVal(v.Elem()) case reflect.Map: return mw.writeMap(v) case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8: return mw.WriteUint64(v.Uint()) case reflect.String: return mw.WriteString(v.String()) case reflect.Slice, reflect.Array: return mw.writeSlice(v) case reflect.Struct: return mw.writeStruct(v) } return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type()) }
func convertNumbersToSameType(leftValue reflect.Value, leftKind reflect.Kind, rightValue reflect.Value, rightKind reflect.Kind) (interface{}, interface{}, Type) { if isInt(leftKind) { if isInt(rightKind) { return leftValue.Int(), rightValue.Int(), Int64 } else if isFloat(rightKind) { return float64(leftValue.Int()), rightValue.Float(), Float64 } } else if isFloat(leftKind) { if isInt(rightKind) { return leftValue.Float(), float64(rightValue.Int()), Float64 } else if isFloat(rightKind) { return leftValue.Float(), rightValue.Float(), Float64 } } else if isComplex(leftKind) && isComplex(rightKind) { return leftValue.Complex(), rightValue.Complex(), Complex128 } return nil, nil, Unknown }
func asInterface(v reflect.Value) interface{} { switch v.Kind() { case reflect.Bool: return v.Bool() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return v.Uint() case reflect.Float32, reflect.Float64: return v.Float() case reflect.Complex64, reflect.Complex128: return v.Complex() case reflect.String: return v.String() default: return v.Interface() } }
func printValue(v reflect.Value) string { switch v.Kind() { case reflect.Bool: return fmt.Sprintf("%t", v.Bool()) case reflect.String: return v.String() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return fmt.Sprintf("%d", v.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return fmt.Sprintf("%d", v.Uint()) case reflect.Float32, reflect.Float64: return fmt.Sprintf("%f", v.Float()) case reflect.Complex64, reflect.Complex128: return fmt.Sprintf("%+v", v.Complex()) default: return fmt.Sprintf("<printVal: %v>", v) } }
// Assumes y is assignable to x, panics otherwise func evalBinaryComplexExpr(ctx *Ctx, x reflect.Value, op token.Token, y reflect.Value) (reflect.Value, error) { var err error var r complex128 xx, yy := x.Complex(), y.Complex() switch op { case token.ADD: r = xx + yy case token.SUB: r = xx - yy case token.MUL: r = xx * yy case token.QUO: r = xx / yy default: err = ErrInvalidOperands{x, op, y} } return reflect.ValueOf(r).Convert(x.Type()), err }
func checkAgainstFloat64(e float64, c reflect.Value) (err error) { err = errors.New("") ck := c.Kind() switch { case isSignedInteger(c): if float64(c.Int()) == e { err = nil } case isUnsignedInteger(c): if float64(c.Uint()) == e { err = nil } // If the actual value is lower precision, turn the comparison around so we // apply the low-precision rules. Otherwise, e.g. Equals(0.1) may not match // float32(0.1). case ck == reflect.Float32 || ck == reflect.Complex64: return Equals(c.Interface()).Matches(e) // Otherwise, compare with double precision. case isFloat(c): if c.Float() == e { err = nil } case isComplex(c): comp := c.Complex() rl := real(comp) im := imag(comp) if im == 0 && rl == e { err = nil } default: err = NewFatalError("which is not numeric") } return }
// isZero returns whether the value is the zero of its type. func isZero(val reflect.Value) bool { switch val.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: return val.Len() == 0 case reflect.Bool: return !val.Bool() case reflect.Complex64, reflect.Complex128: return val.Complex() == 0 case reflect.Chan, reflect.Func, reflect.Ptr: return val.IsNil() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return val.Int() == 0 case reflect.Float32, reflect.Float64: return val.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return val.Uint() == 0 } panic("unknown type in isZero " + val.Type().String()) }
// IsDefaultValue calls SmartCastDefaultValuer to tedect if v in any kind implements // DefaultValuer. If this is the case, then DefaultValuer.IsDefault will be returned. // If v does not implement DefaultValuer, then the result of a comparison with the // zero value of the type will be returned. func IsDefaultValue(v reflect.Value) bool { if defaultValuer, ok := SmartCastDefaultValuer(v); ok { return defaultValuer.IsDefault() } switch v.Kind() { case reflect.String: return v.Len() == 0 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: return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Complex64, reflect.Complex128: return v.Complex() == complex(0, 0) case reflect.Bool: return v.Bool() == false case reflect.Chan, reflect.Func, reflect.Interface, reflect.Slice, reflect.Map: return v.IsNil() case reflect.Ptr: return v.IsNil() || IsDefaultValue(v.Elem()) case reflect.Struct: for i := 0; i < v.NumField(); i++ { if !IsDefaultValue(v.Field(i)) { return false } } return true } panic("never reached") }