CodeBlanks Logo Icon CodeBlanks

Collecting results

Collect results from a separate channel.

Collecting results

The number of results isn't always known. A sturdier way: track the workers with a sync.WaitGroup and close the result channel when all are done. Then the collecting side can use range:

var wg sync.WaitGroup
for w := 0; w < n; w++ {
    wg.Add(1)
    go func() { defer wg.Done(); isci(isler, sonuclar) }()
}
go func() { wg.Wait(); close(sonuclar) }()

for s := range sonuclar { ... }

Order and mapping

Results from concurrent workers arrive in random order. If input order matters, either send the result with its job ID and write it at that index in a slice, or sort the results afterwards:

out := make([]int64, len(dosyalar))
for s := range sonuclar {
    out[s.IsID] = s.Boyut
}

Practice Ordered collection

Each of four jobs (ID 0–3) produces ID * 10. Use two workers, track completion with a WaitGroup, close the result channel and write results into a slice in ID order. Print the slice.

Starter code

main.go
package main

import (
    "fmt"
    "sync"
)

func main() {
    // buraya yaz
}

Sample solution

main.go
package main

import (
    "fmt"
    "sync"
)

type Sonuc struct{ ID, Deger int }

func main() {
    isler := make(chan int)
    sonuclar := make(chan Sonuc)
    var wg sync.WaitGroup
    for w := 0; w < 2; w++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            for id := range isler {
                sonuclar <- Sonuc{id, id * 10}
            }
        }()
    }
    go func() {
        for i := 0; i < 4; i++ {
            isler <- i
        }
        close(isler)
    }()
    go func() {
        wg.Wait()
        close(sonuclar)
    }()
    out := make([]int, 4)
    for s := range sonuclar {
        out[s.ID] = s.Deger
    }
    fmt.Println(out)
}

Expected output

[0 10 20 30]

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why is <code>wg.Add(1)</code> called <strong>before</strong> the goroutine instead of inside it?

  • So Done is called automatically
  • So Wait doesn't run before Add and return early Correct answer
  • Because it's shorter
  • Add doesn't work inside a goroutine

Explanation: If Wait runs before the goroutine starts, the counter looks like zero and Wait returns immediately; Add must happen first.

2 Wait for all

Question
go func() {
    wg.____()
    close(sonuclar)
}()
Answer
go func() {
    wg.Wait()
    close(sonuclar)
}()

Explanation: Wait blocks until every worker calls Done; then the result channel closes safely.

3 Tool

Term Meaning
wg.Add(1) Before the goroutine
defer wg.Done() When the worker ends
wg.Wait + close Close the result channel
out[s.IsID] Keep input order

All lessons in Intermediate