1

Consider the following minimal example:

package main

import "fmt"

type runner interface {
    s1(int)
    s2(int)
}

type test struct {
    x1 []int
    x2 []int
}

func (t test) s1(v int) {
    t.x1 = append(t.x1, v)
    t.s2(v)
}

func (t test) s2(v int) {
    t.x2[v] = v
}


func main() {
    t := test{
        x1: make([]int, 0),
        x2: make([]int, 10)}

    for i := 0; i < 10; i++ {
        t.s1(i)
    }

    fmt.Println(t)
}

Now if you run it, you will get a result like this:

{[] [0 1 2 3 4 5 6 7 8 9]}

meaning that the x1 array is never populated. Or actually, it is, but resets on each time s1 function exits. s2 works just fine placing items in a pre-defined array.

Does anyone know what exactly is going on here? Is it because of the scope of array amends? It seems a little counter intuitive.

P.S. I do understand that x1 is a slice, where x2 is an actual pre-defined array. My own theory goes that if you work with "slices", they can only be changed within a specific scope, not anywhere else.

VoltairePunk
  • 275
  • 4
  • 13
  • 1
    A variation (and thus duplicate) of "values are not modified through methods with value-receivers". – Volker Nov 29 '19 at 08:03

1 Answers1

3

Value receiver makes a copy of the type and pass it to the function.
Just make it pointer and you are good to go:

func (t *test) s1(v int) {
    t.x1 = append(t.x1, v)
    t.s2(v)
}

Output:

&{[0 1 2 3 4 5 6 7 8 9] [0 1 2 3 4 5 6 7 8 9]}

Code:

package main

import "fmt"

type runner interface {
    s1(int)
    s2(int)
}

type test struct {
    x1 []int
    x2 []int
}

func (t *test) s1(v int) {
    t.x1 = append(t.x1, v)
    t.s2(v)
}

func (t test) s2(v int) {
    t.x2[v] = v
}

func main() {
    t := &test{
        x1: make([]int, 0),
        x2: make([]int, 10)}

    for i := 0; i < 10; i++ {
        t.s1(i)
    }

    fmt.Println(t)
}

wasmup
  • 14,541
  • 6
  • 42
  • 58
  • Cool, this is very interesting. Wonder if there's something to read about this particular type of things in go or what was the reasoning for such methodology. It's pretty flexible though. Many thanks for the answer – VoltairePunk Nov 29 '19 at 07:58
  • 2
    Read: [1](https://stackoverflow.com/questions/27775376/value-receiver-vs-pointer-receiver), [2](https://stackoverflow.com/questions/33587227/golang-method-sets-pointer-vs-value-receiver) – wasmup Nov 29 '19 at 08:01