Home  >  Article  >  Backend Development  >  Confused by the suggestion in the official Go guide to use the same type of receiver for all methods

Confused by the suggestion in the official Go guide to use the same type of receiver for all methods

PHPz
PHPzforward
2024-02-10 10:42:08690browse

对 Go 官方指南中关于所有方法使用相同类型接收器的建议感到困惑

#php editor Baicao is confused by the suggestion in the official Go guide to use the same type of receiver for all methods. In the process of learning the Go language, we often encounter the suggestion that the type of the receiver should be consistent when the method is defined. However, this suggestion raises some questions in practical application. To better understand the meaning and purpose of this suggestion, we will explore it in depth and try to find a reasonable explanation.

Question content

I'm trying to learn Go through the official Go tutorial and I found the last part of the section about value vs. pointer receivers confusing:

In general, all methods on a given type should have either a value receiver or a pointer receiver, but not both. (We'll see why in the next few pages.)

Basically, I have two questions:

A) I can't seem to find a reason why we shouldn't mix the two types of receivers for the rest of this chapter, so if anyone could explain or quote a section that discusses this I'd be grateful.

B) Assuming that mixing pointers and value receivers is indeed a bad idea, how do you implement different interfaces? For example, I found that the tutorial described two different built-in interfaces, Stringer and error. In the code provided for Stringer, a value receiver is used, and switching to a pointer receiver doesn't seem to work, whereas in the error interface, a pointer receiver is used. How can I implement these two interfaces for a struct without violating the above principles.

Please note that I've looked at similar questions regarding the disadvantages of using value receivers vs. pointer receivers (e.g. object creation), and the importance of consistency (from this question), but since I'm a real For beginners in Go, I just tried to combine these with information/examples from the official Go tour.

Thanks!

Workaround

For the first problem, having both a value receiver and a pointer receiver can cause a subtle race, since value receivers copy the object. For example:

type T struct {
  field int
}

func (T) ValueReceiver() int {return 1}

func (t *T) SetField(i int) {t.field=i}

In the above example, if you call SetField and ValueReceiver at the same time, you will have a race. This is because, when SetField writes a field, ValueReceiver is creating a copy of the receiver, causing the same field to be read without any explicit synchronization.

For your second question: If you have methods that modify T, then it makes sense to have all methods use pointer receivers. This way you prevent subtle races and implement all interfaces of T.

Here is a link to the FAQ on this topic (thanks to @jub0bs):

https://www.php.cn/link/bcc097feafe80f489ef54b0720ca059c

This example is based on the following post:

https://dave.cheney .net/2015/11/18/wednesday-pop-quiz-spot-the-race

The above is the detailed content of Confused by the suggestion in the official Go guide to use the same type of receiver for all methods. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete