Home > Backend Development > Golang > Why Does Modifying a Simple Type Through a Pointer Receiver Method in Go Not Work as Expected?

Why Does Modifying a Simple Type Through a Pointer Receiver Method in Go Not Work as Expected?

Patricia Arquette
Release: 2024-11-16 12:29:03
Original
237 people have browsed it

Why Does Modifying a Simple Type Through a Pointer Receiver Method in Go Not Work as Expected?

How to Modify Values of Simple Types through Pointer Receiver Methods in Go

When working with custom types based on basic types, you may want to modify their values using pointer receiver functions. However, when you attempt to do so, you may encounter a scenario where the changes appear to be ineffective. Here's a detailed explanation:

The Issue

Consider the following code:

package main

import "fmt"

type FooInt int

func (fi *FooInt) FromString(i string) {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    fi = &tmp // Attempting to modify the pointer
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints nil
}
Copy after login

When you run this program, you'll notice that the value of fi remains nil despite the FromString method's attempt to change it.

Explanation

In Go, all function arguments—including the receiver—are passed by value. This means that inside the FromString method, the fi pointer is a copy of the actual pointer declared in main. When you modify fi within the method, you're only modifying the copy, not the original pointer.

To resolve this issue, you have two options:

1. Return the Modified Pointer

You can return the modified pointer from the FromString method and assign it back to the original pointer:

func (fi *FooInt) FromString(i string) *FooInt {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    return &tmp
}

func main() {
    var fi *FooInt
    fi = fi.FromString("5")
    fmt.Println(fi) // Prints the address of the modified pointer
}
Copy after login

2. Ensure the Receiver is Non-Nil

Alternatively, you can ensure that the receiver is not nil before attempting to modify the pointed value:

func (fi *FooInt) FromString(i string) {
    if fi == nil {
        fi = new(FooInt) // Initialize fi if it's nil
    }
    num, _ := strconv.Atoi(i)
    *fi = FooInt(num)
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints the address of the modified pointer
}
Copy after login

This ensures that the receiver is initialized and the pointed value can be modified directly.

In summary, when modifying values through pointer receiver methods in Go, remember that the receiver is a copy and you must either return the modified pointer or ensure that the receiver is non-nil to avoid unexpected behavior.

The above is the detailed content of Why Does Modifying a Simple Type Through a Pointer Receiver Method in Go Not Work as Expected?. 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