jaimelescornichons
jaimelescornichons

Reputation: 85

golang DeepEqual and reflect.Zero

I'm trying to check if a field in a struct is set to its zero value with reflect.DeepEqual. The idea is that if it is the case, I can change its value with a default one given as a struct tag like following :

type struct {
    A int `default:"42"`
}

My problem is the following : It looks like reflect.DeepEqual is always returning me false. I think I'm missing something. Here is a simple example of what I'm trying to do:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    s := struct{ A int }{0}
    field := reflect.ValueOf(s).Field(0)

    fmt.Println(field.Interface())
    fmt.Println(reflect.Zero(field.Type()))

    fmt.Println(reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type())))
}

And here is a go playground version of the code above : https://play.golang.org/p/k9VY-2Dc69

I would like to know why DeepEqual is returning false in this case.

Thanks!

Upvotes: 2

Views: 2049

Answers (2)

icza
icza

Reputation: 417592

Here:

reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type()))

You are comparing an int value (wrapped in interface{}), to a value of type reflect.Value. reflect.Zero() returns a value of type reflect.Value, not interface{}.

You forgot to call Value.Interface() on the 2nd argument:

reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type()).Interface())

This prints true. Try it on the Go Playground.

Upvotes: 3

Bjorn Roche
Bjorn Roche

Reputation: 11469

The issue has to do with your use of the reflect package.

field.Interface()

Returns an int (wrapped in an interface{}), while

reflect.Zero(field.Type())

returns an object of type reflect.Value. fmt.Println prints them both out the same way, but that doesn't mean they are the same type.

See this playground: https://play.golang.org/p/mLcLSV_0vA

Upvotes: 1

Related Questions