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

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

报告相同问题?

悬赏问题

  • ¥100 数字取证课程 关于FAT文件系统的操作
  • ¥15 如何使用js实现打印时每页设置统一的标题
  • ¥15 安装TIA PortalV15.1报错
  • ¥15 能把水桶搬到饮水机的机械设计
  • ¥15 Android Studio中如何把H5逻辑放在Assets 文件夹中以实现将h5代码打包为apk
  • ¥15 使用小程序wx.createWebAudioContext()开发节拍器
  • ¥15 关于#爬虫#的问题:请问HMDB代谢物爬虫的那个工具可以提供一下吗
  • ¥15 vue3+electron打包获取本地视频属性,文件夹里面有ffprobe.exe 文件还会报错这是什么原因呢?
  • ¥20 用51单片机控制急停。
  • ¥15 孟德尔随机化结果不一致