欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > golang中空值判断函数,支持任意类型的空值判断

golang中空值判断函数,支持任意类型的空值判断

2024/10/24 1:52:22 来源:https://blog.csdn.net/tekin_cn/article/details/140040134  浏览:    关键词:golang中空值判断函数,支持任意类型的空值判断

使用反射方式对any任意类型的数据是否为空判断, 可判断时间对象是否为空, 可判断所有数字类型,指针类型和结构体字符串是否为空

判断规则:

bool类型因为只有true和false 所以 全部视为非空

nil 类型全部视为空

所有数字类型的 零值全部视为空

对应指针类型数据,只要是非nil 则视为非空

对于时间类型结构体或者其他带有 IsZero()方法的结构体 动态调用IsZero()方法来判断是否为空

go代码实现


import ("reflect"
)// 使用反射方式对any任意类型的数据是否为空判断, 可判断时间对象是否为空, 可判断所有数字类型,指针类型和结构体字符串是否为空// 	判断规则:
// 	bool类型因为只有true和false 所以 全部视为非空
// 	nil 类型全部视为空
// 	所有数字类型的 零值全部视为空
// 	对应指针类型数据,只要是非nil 则视为非空
// 	对于时间类型结构体或者其他带有 IsZero()方法的结构体 动态调用IsZero()方法来判断是否为空
//
// @author: tekintian <tekintian@gmail.com>
// @see https://dev.tekin.cn
func IsEmpty(data interface{}) bool {rv := reflect.ValueOf(data)rvk := rv.Kind()switch rvk {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:return rv.IsZero()case reflect.Uintptr, reflect.Map, reflect.Slice, reflect.Pointer, reflect.UnsafePointer:return rv.IsNil() // 指针类型数据全部调用 IsNil() 进行判断,非nil的指针视为非空case reflect.String:return rv.Len() == 0case reflect.Struct:if rv.MethodByName("IsZero").IsValid() {// 动态调用结构体中的 IsZero 方法rt := rv.MethodByName("IsZero").Call([]reflect.Value{}) // call后面的参数即是要调用方法的参数 []reflect.Value{} 表示无参数return len(rt) > 0 && rt[0].Bool()                      // IsZero方法的返回值只有一个bool,} else {// 对值的零值类型进行深度比较return reflect.DeepEqual(rv.Interface(), reflect.Zero(rv.Type()).Interface())}case reflect.Invalid: // nil值的reflect类型就是 Invalidreturn true // nil也算是空值}return false // 其他情况默认非空
}

单元测试用例


import ("gotms/utils""testing""time"
)type DemoSt struct {Name    stringItems   []DemoItemData    interface{}Created time.Time
}
type DemoItem struct {Name string
}func TestIsEmpty(t *testing.T) {cases := []struct {input    interface{}expected bool}{{input: time.Now(), expected: false},{input: DemoSt{}.Created, expected: true}, // 空时间对象 这个是未初始化的时间对象 视为空{input: time.Time{}, expected: true},      // 空时间对象 已经初始化{input: false, expected: false},{input: DemoSt{}.Items, expected: true}, // 这里的DemoSt{}.Items 是一个不可达的对象,即未初始化的对象 视为空{input: DemoSt{}.Data, expected: true},  // nil{input: "", expected: true},{input: 0.0, expected: true},{input: nil, expected: true},{input: complex(0, 0), expected: true}, // 复数的判断{input: complex(2, 1), expected: false},}for _, v := range cases {ret := utils.IsEmpty(v.input)if ret != v.expected {t.Fatalf("%v test failed: expected: %v, got: %v", v.input, v.expected, ret)}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com