Home > Backend Development > Golang > Why Doesn't My Go Struct Setter Function Modify the Original Struct?

Why Doesn't My Go Struct Setter Function Modify the Original Struct?

Mary-Kate Olsen
Release: 2024-12-21 10:00:17
Original
740 people have browsed it

Why Doesn't My Go Struct Setter Function Modify the Original Struct?

Understanding Setters for Struct Types

In Go, structs can be modified through setter functions. However, certain behaviors can be unanticipated when using setters for struct types. Consider the following example:

package main

import "fmt"

type T struct { Val string }

// this setter seems not to work
func (t T) SetVal(s string) {
    t.Val = s
}

// this setter, using ptr to T, seems to work ok
func (t *T) SetVal2(s string) {
    (*t).Val = s
}

func main() {
    v := T{"abc"}
    fmt.Println(v)        // prints {abc}
    v.SetVal("pdq")
    fmt.Println(v)        // prints {abc}, was expecting {pdq}!
    v.SetVal2("xyz")
    fmt.Println(v)        // prints {xyz}!
}
Copy after login

The question arises: why doesn't the SetVal function modify the original struct as expected?

Understanding Value Semantics

The key difference lies in how structs are passed to functions. When passing a struct by value (as in SetVal), a copy of the struct is created within the function. Any changes made within the function will affect only this temporary copy, leaving the original struct unchanged.

However, when passing a struct by pointer (as in SetVal2), the function gains access to the original struct in memory. Any changes made within the function will be directly reflected in the original struct.

Proof of Value Semantics

This can be illustrated by printing the memory addresses of the structs involved:

package main

import "fmt"

type T struct { Val string }

func (t T) SetVal(s string) {
    fmt.Printf("Address of copy is %p\n", &t)
}

func (t *T) SetVal2(s string) {
    fmt.Printf("Pointer argument is %p\n", t)
}

func main() {
    v := T{"abc"}
    fmt.Printf("Address of v is %p\n", &v)
    v.SetVal("pdq")
    v.SetVal2("xyz")
}
Copy after login

This code will produce output resembling:

Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290
Copy after login

Note that the first and third addresses printed are the same, indicating that they refer to the same struct. However, the second address is different, representing the temporary copy created within SetVal.

The above is the detailed content of Why Doesn't My Go Struct Setter Function Modify the Original Struct?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template