混淆延迟wg。完成和频道

I encounter a problem about using defer wg.Done and channel.

If I coded like below, there is no problem.

for i := 0; i < ntasks; i++ {
    wg.Add(1)
    go func(args DoTaskArgs) {
        // defer wg.Done()
        for {
            worker := <-registerChan
            ok := call(worker, "Worker.DoTask", &args, nil)
            if ok {
                wg.Done()
                // go func() {
                registerChan <- worker
                // }()
                break
            }
        }
    }(DoTaskArgs{jobName, mapFiles[i], phase, i, n_other})
}
wg.Wait()

But if I use defer wg.Done(), the code would be stucked, unless wrap the registerChan <- worker with go func.

for i := 0; i < ntasks; i++ {
    wg.Add(1)
    go func(args DoTaskArgs) {
        defer wg.Done()
        for {
            worker := <-registerChan
            ok := call(worker, "Worker.DoTask", &args, nil)
            if ok {
                // go func() {
                registerChan <- worker
                // }()
                break
            }
        }
    }(DoTaskArgs{jobName, mapFiles[i], phase, i, n_other})
}
wg.Wait()

What is the problem here?

Well, first off, your channel use is confused and will block. In the goroutine it reads from the channel. But nothing wrote into it.

I don't think your problem has anything to do with defer.