dsfsdf5646 2018-09-28 20:38
浏览 7
已采纳

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

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
", 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.

  • 写回答

1条回答 默认 最新

  • dtjpz48440 2018-09-28 21:13
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了