简体   繁体   English

如何使用反射在Go中查找空结构值?

[英]How to find empty struct values in Go using reflection?

I have been looking and been struggling with this for a bit. 我一直在寻找,并为此付出了一些努力。 I found this other Stack Overflow question which put me in the right direction but isn't working: Quick way to detect empty values via reflection in Go . 我发现了另一个另一个Stack Overflow问题,该问题使我朝着正确的方向前进,但没有用: 通过Go中的反射检测空值的快速方法

My current code looks like this: 我当前的代码如下所示:

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)
    }
}

However I have fmt.Printf which prints out the val and the reflect.Zero I have, and even when they both are the same, it still goes into the if statement and every single field is read as non-zero even though that is clearly not the case. 但是我有fmt.Printf可以打印出valreflect.Zero我有,即使它们都相同,它仍然进入if语句,每个字段都读为非零,即使这很明显并非如此。 What am I doing wrong? 我究竟做错了什么? I don't need to update the fields, just add them to the slice values if they aren't zero. 我不需要更新字段,只需将它们添加到切片值(如果它们不为零)。

For starters, you are adding val to the values slice if val IS the zero value, not if it isn't. 对于初学者来说,要添加valvalues切片如果val 零值,而不是如果它不是。 So you should probably check if !reflect.DeepEqual(... instead of what you have. Other than that, your code seems to work fine: 因此,您可能应该检查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)
        }
    }
}

outputs the following ( Go Playground Link ): 输出以下内容( 转到Playground Link ):

Name is non-zero, adding to update
Age is non-zero, adding to update

So it is correctly seeing that the Email field is not initialized (or more correctly, contains the zero value for string ). 因此,可以正确地看到未初始化Email字段(或更正确地说,它包含string的零值)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM