Home >Backend Development >Golang >Why Can\'t I Modify a Simple Type Value Through a Pointer Receiver Method in Go?

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

Barbara Streisand
Barbara StreisandOriginal
2024-11-19 01:12:02342browse

Why Can't I Modify a Simple Type Value Through a Pointer Receiver Method in Go?

Modifying Simple Type Values through Pointer Receiver Methods in Go

In Go, we can create custom types based on basic types and extend their functionality through pointer receiver methods. However, there is a common question that arises when attempting to modify the value of a simple type through a pointer receiver method.

Consider the following example:

package main

import (
    "fmt"
    "strconv"
)

type FooInt int

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

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

Why does the pointer fi declared in main() not change its value to the address of tmp?

Explanation

When you call a function or method in Go, all arguments, including the receiver, are passed as copies. This means you cannot modify the original pointer value from within the function/method.

In the example above, fi in the FromString method is a copy of the pointer declared in main(). When you assign fi to the address of tmp, you are only changing the value of the copy. The original pointer remains unchanged.

Solutions

There are three common solutions to this problem:

1. Returning a 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. Passing a Pointer Argument:

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

func main() {
    var fi *FooInt
    fi = new(FooInt) // Ensure non-nil receiver
    fi.FromString("5", &fi)
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}

3. Ensuring Non-Nil Receiver:

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

func main() {
    var fi *FooInt
    fi = new(FooInt) // Ensure non-nil receiver
    fi.FromString("5")
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}

The above is the detailed content of Why Can\'t I Modify a Simple Type Value Through a Pointer Receiver Method 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