我一直在寻找并且一直为此苦苦挣扎。我发现了另一个“堆栈溢出”问题,该问题使我朝着正确的方向前进,但无法正常工作:Quick way to detect empty values via reflection in Go。
我当前的代码如下:
structIterator := reflect.ValueOf(user)
for i := 0; i < structIterator.NumField(); i++ {
field := structIterator.Type().Field(i).Name
val := structIterator.Field(i).Interface()
// Check if the field is zero-valued, meaning it won't be updated
if reflect.DeepEqual(val, reflect.Zero(structIterator.Field(i).Type()).Interface()) {
fmt.Printf("%v is non-zero, adding to update\n", field)
values = append(values, val)
}
}
但是我有fmt.Printf
可以打印出我拥有的val
和reflect.Zero
,即使它们相同,它仍然会进入if
语句并且每个字段都被读为非零,即使事实并非如此。我究竟做错了什么?我不需要更新字段,只需将它们添加到切片 values (如果它们不为零)即可。
答案 0 :(得分:2)
对于初学者,如果val
IS 为零,则将values
添加到val
切片中,如果不是,则为零。因此,您可能应该检查if !reflect.DeepEqual(...
而不是所拥有的。除此之外,您的代码似乎可以正常工作:
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string
Age int
Email string
}
func main() {
user, values := User{Name: "Bob", Age: 32}, []interface{}(nil)
structIterator := reflect.ValueOf(user)
for i := 0; i < structIterator.NumField(); i++ {
field := structIterator.Type().Field(i).Name
val := structIterator.Field(i).Interface()
// Check if the field is zero-valued, meaning it won't be updated
if !reflect.DeepEqual(val, reflect.Zero(structIterator.Field(i).Type()).Interface()) {
fmt.Printf("%v is non-zero, adding to update\n", field)
values = append(values, val)
}
}
}
输出以下(Go Playground Link):
Name is non-zero, adding to update
Age is non-zero, adding to update
因此可以正确地看到Email
字段未初始化(或更正确地说,它包含string
的零值)。