Home  >  Article  >  Backend Development  >  Why Can\'t I Modify a Simple Type\'s Value Using a Pointer Receiver in Go?

Why Can\'t I Modify a Simple Type\'s Value Using a Pointer Receiver in Go?

Barbara Streisand
Barbara StreisandOriginal
2024-11-16 06:53:03234browse

Why Can't I Modify a Simple Type's Value Using a Pointer Receiver in Go?

How to Modify a Simple Type's Value via a Pointer Receiver in Go?

In Go, pointer receivers in methods allow you to modify the original value of a struct. However, this doesn't apply to simple types. This question delves into why such modifications don't work and presents solutions.

Problem

Consider this code:

package main

import (
    "fmt"
    "strconv"
)

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

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Printf("%v\n", fi) // Prints <nil>
}

Here, you'd expect the function FromString to set the value of fi to 5. But it prints , indicating a nil pointer.

Understanding the Behavior

In Go, function/method arguments, including the receiver, are copies of the original values. As a result, modifications within the function only affect the copy.

Even for pointers, the receiver is a copy of the original pointer, not the actual pointer itself. Thus, modifications made to the receiver's value won't affect the original pointer.

Solutions

To resolve this, there are several options:

  1. Return the Modified Pointer:

    • Modify the function to return the modified pointer and assign it 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.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
    }
  2. Pass a Pointer to Modify:

    • Pass a non-nil pointer of the desired type to the function, and modify its value.
    func (fi *FooInt) FromString(i string, p **FooInt) {
        num, _ := strconv.Atoi(i)
        tmp := FooInt(num)
        *p = &tmp
    }
    
    func main() {
        var fi *FooInt
        fi.FromString("5", &fi)
        fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
    }
  3. Ensure Non-Nil Receiver:

    • Initialize the receiver to a non-nil value before calling the method, so the pointed value can be modified.
    func (fi *FooInt) FromString(i string) {
        num, _ := strconv.Atoi(i)
        *fi = FooInt(num)
    }
    
    func main() {
        fi := new(FooInt) // Initialize to non-nil
        fi.FromString("5")
        fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
    }

By adopting one of these solutions, you can effectively modify the value of simple types using pointer receivers.

The above is the detailed content of Why Can\'t I Modify a Simple Type\'s Value Using a Pointer Receiver in Go?. 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