Home > Blockchain >  golang why comparing two variables pointing to struct behaves differently?
golang why comparing two variables pointing to struct behaves differently?

Time:02-11

I have created two instances of same struct, Confused by the output when I compare two variables point to instances of struct.

package main

import "fmt"

type Person struct {
    name string
}

func main() {
   p1 := &Person{name: "guru"}
   p2 := &Person{name: "guru"}
   fmt.Println(p1 == p2) // false, compares by address?
   p3 := Person{name: "guru"}
   p4 := Person{name: "guru"}
   fmt.Println(p3 == p4) // true , why? compares by content?
}

does == operator works like overload operator?

CodePudding user response:

p1 == p2 is pointer comparison, it compares the pointer values (the memory addresses). Since you used 2 composite literals (and took their addresses), they will point to 2 distinct variables, so the addresses will be different (since size of Person is not zero). Spec: Composite literals:

Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.

p3 == p4 compares struct values, it compares them field-by-field, and since the matching fields have equal values, the comparison will result in true.

Comparison rules are in Spec: Comparison operators:

The equality operators == and != apply to operands that are comparable. The ordering operators <, <=, >, and >= apply to operands that are ordered. These terms and the result of the comparisons are defined as follows:

  • [...]
  • Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.
  • [...]
  • Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.

CodePudding user response:

Your first example

p1 := &Person{name: "guru"}
p2 := &Person{name: "guru"}

fmt.Println(p1 == p2) // false, compares by address?

compares two pointers for equality. Since they each address different memory addresses, the do not compare as equal.

Your second example,

 p3 := Person{name: "guru"}
 p4 := Person{name: "guru"}

fmt.Println(p3 == p4) // true , why? compares by content?

compares two struct and does so by value, so they compare equal.

If you dereference the pointer before the comparison, you'll find that they compare as equal. For instance, given

p1 := &Person{ name: "guru" }
p2 := &Person{ name: "guru" }
p3 :=  Person{ name: "guru" }
p4 :=  Person{ name: "guru" }

All of the following compare as equal:

  • *p1 == *p2
  • *p1 == p3
  • p3 == *p2
  • p3 == p4

CodePudding user response:

Two pointers values are only equal when they point to the same value in the memory or if they are nil in Golang. You create two instances of struct, thus they have different address

   p1 := &Person{name: "guru"}
   p2 := &Person{name: "guru"}
  • Related