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

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

报告相同问题?

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能