简体   繁体   中英

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 .

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. 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. So you should probably check if !reflect.DeepEqual(... instead of what you have. Other than that, your code seems to work fine:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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