Home >Backend Development >Golang >Why Does a Go Method with a Pointer Receiver Modify a Non-Pointer Argument?

Why Does a Go Method with a Pointer Receiver Modify a Non-Pointer Argument?

Barbara Streisand
Barbara StreisandOriginal
2024-12-05 11:35:11485browse

Why Does a Go Method with a Pointer Receiver Modify a Non-Pointer Argument?

Why Method with Pointer Receiver Still Changes Value when Receives Non-Pointer?

In Go, methods with pointer receivers are known to preserve the original values of variables they operate on. However, there seems to be an apparent contradiction when a method expects a pointer argument and is passed a non-pointer value.

Consider the below snippet for Exercise 51 in the Tour of Go:

func (v *Vertex) Scale(f float64) {
    v.X *= f
    v.Y *= f
}

func main() {
    v := &Vertex{3, 4}
    v.Scale(2)
    fmt.Println(v) // Output: &{6 8}
}

According to the explanation, the Scale method should not modify v since it receives a pointer to a Vertex (*Vertex) instead of a Vertex itself.

However, when we change the v := &Vertex{3, 4} line to v := Vertex{3, 4} in main, the output changes from &{6 8} to {6 8} (notice the missing &). This indicates that v has been modified, even though it was passed as a non-pointer value.

The Explanation

The key lies in Go's strongly typed nature and compiler optimizations. Even though the Scale method expects a pointer receiver, it can still accept non-pointer values because Go implicitly converts them to pointers.

Specifically, the compiler rewrites the following code:

v := Vertex{3, 4}
v.Scale(2)

to:

(&v).Scale(2)

This means the method is actually called with a pointer to v, which allows it to modify the original value.

The following Go-specific rule explains this behavior:

A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

In summary, methods with pointer receivers can still modify non-pointer variables because the compiler automatically converts them to pointers to preserve method type safety.

The above is the detailed content of Why Does a Go Method with a Pointer Receiver Modify a Non-Pointer Argument?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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