4
search [160c2f4e2006a2 brain into the fried fish ] follow this fried fish with liver-fried liver. This article GitHub github.com/eddycjy/blog has been included, and there are my series of articles, materials and open source Go books.

Hello everyone, I am fried fish.

A few days ago, I shared "Are Go Structures Comparable? Why? ", a small partner raised a new question:

来自文章评论区

Although the speed of people asking questions has surpassed the speed of this fish writing articles... But as a pet fanatic, I still wrote this article during the Qingming holiday at this moment.

I searched for related issues while surfing the Internet and found that there were Go developers who had exactly the same questions 6 years ago, which really troubled generations of friends.

来自 stackoverflow.com

The hero of this issue is " Go structure and structure pointer call ", I hope it will be helpful to everyone and bring some thoughts.

Please mute here the answer your mind, and then discuss a wave of Go technology philosophy with fried fish.

What is the structure

There is a basic type in the Go language, which developers call a struct. It is very commonly used in the Go language, the basic definition:

type struct_variable_type struct {
    member definition
    member definition
    ...
    member definition
}

Simple example:

package main

import "fmt"

type Vertex struct {
    Name1 string
    Name2 string
}

func main() {
    v := Vertex{"脑子进了", "煎鱼"}
    v.Name2 = "蒸鱼"
    fmt.Println(v.Name2)
}

Output result:

蒸鱼

This part is basic knowledge, so I won't explain it too much. If you don't understand it, it is recommended to relearn the basics of Go language grammar.

Structure and pointer call

After explaining the pre-summary, go directly to the topic of this article. The following example:

type MyStruct struct {
    Name string
}

func (s MyStruct) SetName1(name string) {
    s.Name = name
}

func (s *MyStruct) SetName2(name string) {
    s.Name = name
}

The program declares a User structure, which contains two structure methods, namely SetName1 and SetName2 methods. The difference between the two is that the references are different in .

Extending further, what is the difference between the two, which one should be used under what circumstances, and are there any precautions?

Note: Coincidentally, I have a friend who struggled with this problem when he first started using the Go language.

The difference between the two

Judging from the feedback from many small partners, the difference between these two examples may be confusing. People often wonder whether to use "pointers" and worry about GC or something.

In fact, the situation is not that complicated. Take a look at the following example:

func (s MyStruct) SetName1(name string) 
func (s *MyStruct) SetName2(name string)

When defining a method on a type, the receiver (s in the example above) behaves as if it were a parameter of the method. It is equivalent to:

 func SetName1(s MyStruct, name string){
    u.Name = name
 }

 func SetName2(s *MyStruct,name string){
    u.Name = name
 }

Therefore, the structure method is to define the receiver as a value or a pointer. This is essentially the same question as whether a function parameter should be a value or a pointer.

how to choose

There are several considerations as a whole, arranged in order of importance:

  1. Considerations in use: Does the method need to modify the receiver? If needed, the receiver must be a pointer.
  2. In terms of efficiency: If the receiver is large, such as a large structure, it will be much better to use a pointer receiver.
  3. Consistency considerations: If some methods of the type must have pointer receivers, then the rest of the methods should also have pointer receivers, so no matter how the type is used, the method set is consistent.

Going back to the above example, from the perspective of function usage:

  • If the SetName2 method modifies the fields of s, the caller can see the changes in the values of these fields, because it is a pointer reference, which is essentially the same.
  • Compared with the SetName1 method, the method is called with a copy of the caller's parameters, which is essentially value transfer, and any field changes it makes are invisible to the caller.

In addition, value receivers are very cheap for basic types, slices, and small structures.

So unless the semantics of the method require pointers, then the value receiver is the most efficient and clear. In terms of GC, there is no need to pay too much attention. Just solve it when it appears.

to sum up

In this article, we analyze and explain the difference between Go structure and structure pointer call. This problem is analyzed and explained in a simple way.

And part of the content introduced in this article comes from the official FAQ "Should I define methods on values or pointers?", which can be considered as the basic answer given by the official (there are really many people asking).

Whoever wonders about this issue, forward this article and it will be over.

If you have any questions please comment and feedback exchange area, best relationship is mutual achievement , everybody thumbs is fried fish maximum power of creation, thanks for the support.

The article is continuously updated, and you can read it on [My brain is fried fish], and reply [160c2f4e200a72 000 ] I have prepared the first-line interview algorithm questions and information; this article GitHub github.com/200adycjy github.com/blog 16078 has been included , Welcome Star to urge you to update.

煎鱼
8.4k 声望12.8k 粉丝