Как найти пустые значения структуры в Go, используя отражение? - PullRequest
0 голосов
/ 28 сентября 2018

Я искал и боролся с этим немного.Я нашел этот другой вопрос переполнения стека, который направил меня в правильном направлении, но не работает: Быстрый способ обнаружения пустых значений с помощью отражения в Go .

Мой текущий код выглядит следующим образом:

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

Однако у меня есть fmt.Printf, который распечатывает val и reflect.Zero, которые у меня есть, и даже когда они оба одинаковы, он все равно входит в оператор if и каждыйодиночное поле читается как ненулевое, хотя это явно не так.Что я делаю неправильно?Мне не нужно обновлять поля, просто добавьте их к фрагменту значения , если они не равны нулю.

1 Ответ

0 голосов
/ 29 сентября 2018

Для начала, вы добавляете val к срезу values, если val IS нулевое значение, а не если это не так.Так что вам стоит проверить 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)
        }
    }
}

выводит следующее ( Go Playground Link ):

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

Так что это правильно,поле Email не инициализировано (или, вернее, содержит нулевое значение для string).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...