2

I have just started playing with Go and stumbled upon problem how the pointers are handled in this language.

I have such code and can`t figure out how to fix it to get the correct response.

Changing func (me *Str) Start() to func (me Str) Start() fixes the problem, but I need this as reference to write this structure (it will have channel in it).

Sample code (https://play.golang.org/p/EsPejyCrX7):

package main

import (
    "fmt"
    "sync"
)

var wg1 sync.WaitGroup

type Str struct {
    id int
}

func (me *Str) Start() {
    wg1.Add(1)
    fmt.Println("F1 ", me)
    go me.startFn()
}

func (me *Str) startFn() {
    defer wg1.Done()
    fmt.Println("F2 ", me)
}

func main() {
    Fl2 := []Str{
        {1},
        {2},
        {3},
    }

    for _, fl := range Fl2 {
        fl.Start()
    }
    wg1.Wait()
}

Response:

F1  &{1}
F1  &{2}
F1  &{3}
F2  &{3}
F2  &{3}
F2  &{3}

Expected response (F2 can be random):

F1  &{1}
F1  &{2}
F1  &{3}
F2  &{3}
F2  &{2}
F2  &{1}

1 Answer 1

3

Using goroutines on loop iterator variables is a common mistake.

Call .Start on the element of Fl2 by the range index, instead of the range value (playground):

for i := range Fl2 {
    Fl2[i].Start()
}

However, the output might still not become exactly as you expect, due to the scheduling of the goroutines, for example it might be like this:

F1  &{1}
F1  &{2}
F1  &{3}
F2  &{3}
F2  &{1}
F2  &{2}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that fixes it. Are you able to explain why changing to (&fl).Start() does not fix it? I though in Go it will return me the underlying structure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.