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

PHPz
Release: 2024-02-10 10:42:08
forward
692 people have browsed it

对 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}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!