1

Looking at the following golang code:

b := []byte(`["a", "b"]`)
var value interface{}
json.Unmarshal(b, &value)
fmt.Println(value)                 // Print [a b]
fmt.Println(reflect.TypeOf(value)) //Print []interface {}
var targetValue interface{} = []string{"a", "b"}
if reflect.DeepEqual(value.([]interface{}), targetValue) {
    t.Error("please be equal")
}

Am I expecting too much of DeepEqual? Reading the documentation, the following statements reinforce my assumption that it should work:

  • Array values are deeply equal when their corresponding elements are deeply equal.
  • Interface values are deeply equal if they hold deeply equal concrete values.
  • Slice values are deeply equal when (...) or their corresponding elements (up to length) are deeply equal.

What am I missing here?

Nathan H
  • 48,033
  • 60
  • 165
  • 247
  • You may find these interesting. [Package for equality of Go values: google/go-cmp](https://github.com/google/go-cmp). [Life of a Go Infrastructure Maintainer](https://medium.com/@zombiezen/life-of-a-go-infrastructure-maintainer-cb1419308eb5). – peterSO Mar 06 '18 at 15:57

1 Answers1

5

You're comparing a []interface{} against []string, which should never be equal.

if reflect.DeepEqual(value.([]interface{}), targetValue) {

compared against targetValue which is of type []string:

var targetValue interface{} = []string{"a", "c"}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • Understood. I assumed they would both be interfaces, or both []string. I guess this would fall under "Values of distinct types are never deeply equal.". What can I do to make them of the same type to I can compare? – Nathan H Mar 06 '18 at 14:41
  • Got it! Instead of declaring my targetValue with literal values, I use `append()`. Doing this preserves the `[]interface{}` type. – Nathan H Mar 06 '18 at 14:51
  • 2
    The easy way in your specific case would be: `var targetValue interface{} = []interface{}{"a", "b"}` – Jonathan Hall Mar 06 '18 at 14:52
  • Indeed that's even better. Can you update your answer? – Nathan H Mar 06 '18 at 14:54
  • yeap, as @Flimzy mentioned, if you declare it as []interface{}, then the types would be same and hence, reflect would deep equal should give out true - https://play.golang.org/p/iN3STrExW64 – vedhavyas Mar 06 '18 at 14:55
  • @Flimzy can you update your answer with your suggestion, so the answer will be complete? – Nathan H Mar 07 '18 at 07:30