gpt4 book ai didi

go - 如何获取字段类型的零值

转载 作者:IT老高 更新时间:2023-10-28 13:04:29 25 4
gpt4 key购买 nike

我有一个包含许多字段的结构 - 我已经弄清楚如何使用反射提取字段名称、值和标记信息。我还想做的是确定一个字段的值是否与该字段的默认值不同。

目前,我有这个(有效,但有点臭):

...
qsMap := make(map[string]interface{})
var defaultTime time.Time
var defaultString string
...
// get the field name and value
fieldName := s.Type().Field(i).Tag.Get("bson")
fieldValue := valueField.Interface()

// use reflection to determine the TYPE of the field and apply the proper formatting
switch fieldValue.(type) {
case time.Time:
if fieldValue != defaultTime {
qsMap[fieldName] = fieldValue
}
case string:
if fieldValue != defaultString {
qsMap[fieldName] = fieldValue
}
...
}

在我看来,在这种情况下应该有一种方法可以避免类型切换 - 我要做的是建立一个字段/值的映射,其值不同于其默认零值,例如:

// doesn't work -- i.e., if fieldValue of type string would be compared against "", etc.
if fieldValue != reflect.Zero(reflect.Type(fieldValue)) {
qsMap[fieldName] = fieldValue
}

有没有优雅的方法来完成这个?

谢谢!

最佳答案

对于支持相等操作的类型,您可以只比较 interface{} 变量持有零值和字段值。像这样的:

v.Interface() == reflect.Zero(v.Type()).Interface()

但是对于函数、 map 和 slice ,这种比较会失败,所以我们仍然需要包含一些特殊的大小写。此外,虽然数组和结构是可比较的,但如果它们包含不可比较的类型,则比较将失败。所以你可能需要这样的东西:

func isZero(v reflect.Value) bool {
switch v.Kind() {
case reflect.Func, reflect.Map, reflect.Slice:
return v.IsNil()
case reflect.Array:
z := true
for i := 0; i < v.Len(); i++ {
z = z && isZero(v.Index(i))
}
return z
case reflect.Struct:
z := true
for i := 0; i < v.NumField(); i++ {
z = z && isZero(v.Field(i))
}
return z
}
// Compare other types directly:
z := reflect.Zero(v.Type())
return v.Interface() == z.Interface()
}

关于go - 如何获取字段类型的零值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23555241/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com