切片的长度因已使用waitgroup而有所不同

I have a hard time understanding concurrency/paralel. in my code I made a loop of 5 cycle. Inside of the loop I added the wg.Add(1), in total I have 5 Adds. Here's the code:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var list []int
    wg := sync.WaitGroup{}
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(c *[]int, i int) {
            *c = append(*c, i)
            wg.Done()
        }(&list, i)
    }
    wg.Wait()
    fmt.Println(len(list))
}

The main func waits until all the goroutines finish but when I tried to print the length of slice I get random results. ex (1,3,etc) is there something that is missing for it to get the expected result ie 5 ?

is there something that is missing for it to get the expected result ie 5 ?

Yes, proper synchronization. If multiple goroutines access the same variable where at least one of them is a write, you need explicit synchronization.

Your example can be "secured" with a single mutex:

var list []int
wg := sync.WaitGroup{}

m := &sync.Mutex{} // A mutex

for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(c *[]int, i int) {
        m.Lock() // Must lock before accessing shared resource
        *c = append(*c, i)
        m.Unlock() // Unlock when we're done with it
        wg.Done()
    }(&list, i)
}
wg.Wait()

fmt.Println(len(list))

This will always print 5.

Note: the same slice is read at the end to prints its length, yet we are not using the mutex there. This is because the use of waitgroup ensures that we can only get to that point after all goroutines that modify it have completed their job, so data race cannot occur there. But in general both reads and writes have to be synchronized.

See possible duplicates:

go routine not collecting all objects from channel

Server instances with multiple users

Why does this code cause data race?

How safe are Golang maps for concurrent Read/Write operations?

golang struct concurrent read and write without Lock is also running ok?

See related questions:

Can I concurrently write different slice elements

If I am using channels properly should I need to use mutexes?

Is it safe to read a function pointer concurrently without a lock?

Concurrent access to maps with 'range' in Go