there is such a small piece of code.

type Person struct { Name string Power int } func (p *Person) Super() { p.Power += 1000 } func main() { p := Person{"Mike", 1000} p.Super() fmt.Println(p.Power) } 

But sometimes I see that when declaring a structure, an ampersand is given, &Person{"Mike", 1000} what is the purpose of this? because the conclusion is the same.

    3 answers 3

    A pointer is an object reference. If we refer to an object by reference and change the data, then the data changes from the original object. If we address by value, then, as it were, we copy the object, if we change its data, the original object will remain the same.

    For example, we create Mike. Obviously, the person does not need to copy, so it is better to save the link. Suppose Mike enters the Family and Work structures:

     type Person struct { Name string Age int } func (p *Person) GrowUp() { p.Age += 1 } type Family struct { Husband *Person Wife *Person } type Work struct { Director *Person Employees []*Person } func main() { p := &Person{Name: "Mike", Age: 30} f := Family{Husband: p} w := Work{Director: p} } 

    Those. if you take the age from the husband in the family f and from the director in the company w - it will be 30 years. Then Mike matured p.GrowUp() . And if we again check the age of the husband and the director, we get 31.

     func main() { p := &Person{Name: "Mike", Age: 30} f := Family{Husband: p} w := Work{Director: p} p.GrowUp() fmt.Println(f.Husband.Age, w.Director.Age) } 

    https://play.golang.org/p/Vn_uLZd6zuR

    If you remove the pointers, then after changing the age of Mike, the age of the director and the age of the husband will not change - https://play.golang.org/p/lJNW2I9rcC5

      if you write like this

       p := Person{"Mike", 1000} 

      then p is just a variable of type Person structure

      If so

       p := &Person{"Mike", 1000} 

      then p is a pointer to a structure of type Person

      And if in the second case you can print the value like this

       fmt.Println(*p) 

      That, in the first so it is impossible to do.

      But why is the conclusion the same? just go hides in many cases the difference between a pointer and just a variable.

      • As I understand it, * it simply indicates that something can be put into this memory area, and another question you wrote, p - это указатель на структуру типа Person but still, why is it here? doing some extra features? Thank! - Mike Yusko
      • an asterisk is either an indication that the type is a pointer, or a pointer dereference. What exactly she does - you need to look at the context. Why is there a pointer? I don't know, but sometimes he is very much needed. For example, if the object is very large, and we have an array of such objects, then copying all this can take a long time. - KoVadim

      The Super method as the receiver requires the * Person type, but in the code the argument is the Person type. In such cases, the compiler implicitly receives the address of the receiver argument and passes it to the method being called. If, however, you call Super at once with the recipient * Person argument, then implicitly getting the address is not required. This is done to simplify the code and not to write the following:

       (&p).Super() 

      Conversely, if Super required the Person type as the receiver, and was called with the * Person argument, the compiler would implicitly perform pointer dereferencing and Super would get a copy of the Person instance.