Hi, @laiboonh,
Firstly, your Even
function isn’t closing over count
. count
is a global variable that both main
and Even
have access to.
Secondly, though I understand that you know other languages and therefore I suspect you’re just trying to learn how to do concurrency in Go, here’s how I’d implement your program:
I think the right way to do this is to change Even
so that instead of receiving a slice and updating the global count
variable, you should change it to this:
func Even(arr []int) int {
count := 0
for _, item := range arr {
if item%2 == 0 {
count++
}
}
return count
}
And then you use it from main
like this:
func main() {
arr := makeRange(1, 100000)
count := Even(arr)
fmt.Println(count)
}
Without this change, if you had another goroutine running that was also counting the number of even values with your Even
function, they’d both be sharing that same count
and both return the wrong value. Writing the function this new way makes it safe to use concurrently and sets us up for a slightly different example that I’d like to use to demonstrate the motivation for using a goroutine:
The go
keyword starts a goroutine but doesn’t wait for it. You want to use goroutines when you want to run a function and then do other stuff without waiting (or while waiting) for that other function to finish. In your case, beause you’re just counting the number of even values and then only after you have the count, you want to print it out, you won’t get any benefit (in terms of performance or in terms of learning) in running Even
in another goroutine. With the change I put above, though, you could instead run multiple Even
functions in multiple goroutines:
import "sync"
func main() {
arr := makeRange(1, 100000)
wg := sync.WaitGroup{}
wg.Add(2)
firstHalf, secondHalf := 0, 0
go func() {
firstHalf = Even(arr[:50000])
wg.Done()
}()
go func() {
secondHalf = Even(arr[50000:])
wg.Done()
}()
wg.Wait()
fmt.Println(firstHalf + secondHalf)
}
This implementation executes Even
in two goroutines and uses a sync.WaitGroup
to, well, wait for the goroutines to finish counting the even numbers from both halfs of the slice.