Search code examples
multithreadingpointersgomapsgoroutine

Issue modifying map from goroutine func


scores := make(map[string]int)
percentage := make(map[string]float64)
total := 0

for i, ans := range answers {
    answers[i] = strings.ToLower(ans)
}

wg := sync.WaitGroup{}

go func() {
    wg.Add(1)

    body, _ := google(question)

    for _, ans := range answers {
        count := strings.Count(body, ans)
        total += count
        scores[ans] += 5 // <------------------- This doesn't work
    }

    wg.Done()
}()

Here's a snippet of code, my issue is, that I am unable to modify the scores, I've tried using pointers, I've tried doing it normally, I've tried passing it as a parameter.


Solution

  • Package sync

    import "sync"

    type WaitGroup

    A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.


    You have provided us with a non-working fragment of code. See How to create a Minimal, Complete, and Verifiable example.

    As a guess, your use of a sync.WaitGroup looks strange. For example, by simply following the instructions in the sync.Waitgroup documentation, I would expect something more like the following:

    package main
    
    import (
        "fmt"
        "strings"
        "sync"
    )
    
    func google(string) (string, error) { return "yes", nil }
    
    func main() {
        question := "question?"
        answers := []string{"yes", "no"}
    
        scores := make(map[string]int)
        total := 0
    
        wg := sync.WaitGroup{}
        wg.Add(1)
        go func() {
            defer wg.Done()
    
            body, _ := google(question)
            for _, ans := range answers {
                count := strings.Count(body, ans)
                total += count
                scores[ans] += 5 // <-- This does work
            }
        }()
        wg.Wait()
    
        fmt.Println(scores, total)
    }
    

    Playground: https://play.golang.org/p/sZmB2Dc5RjL

    Output:

    map[yes:5 no:5] 1