对于范围与静态通道长度golang

I have a channel taking events parsed from a log file and another one which is used for synchronization. There were 8 events for the purpose of my test.

When using the for range syntax, I get 4 events. When using the known number (8), I can get all of them.

func TestParserManyOpinit(t *testing.T) {
    ch := make(chan event.Event, 1000)
    done := make(chan bool)
    go parser.Parse("./test_data/many_opinit", ch, done)
    count := 0
    exp := 8
    evtList := []event.Event{}

    <-done
    close(ch)
    //This gets all the events
    for i := 0; i < 8; i++ {
            evtList = append(evtList, <-ch)
            count++
    }

    //This only gives me four
    //for range ch {
    //        evtList = append(evtList, <-ch)
    //        count++
    //}

    if count != exp || count != len(evtList) {
            t.Errorf("Not proper lenght, got %d, exp %d, evtList %d", count, exp, len(evtList))
    }

func Parse(filePath string, evtChan chan event.Event, done chan bool) {
    log.Info(fmt.Sprintf("(thread) Parsing file %s", filePath))
    file, err := os.Open(filePath)
    defer file.Close()

    if err != nil {
            log.Error("Cannot read file " + filePath)
    }
    count := 0
    scan := bufio.NewScanner(file)
    scan.Split(splitFunc)
    scan.Scan() //Skip log file header

    for scan.Scan() {
            text := scan.Text()
            text = strings.Trim(text, "
")
            splitEvt := strings.Split(text, "
")
            // Some parsing ...
            count++
            evtChan <- evt
    }

    fmt.Println("Done ", count) // gives 8
    done <- true
}

I must be missing something related to for loops on a channel.

I've tried adding a time.Sleep just before the done <- true part. It didn't change the result.

When you use for range, each loop iteration reads from the channel, and you're not using the read value. Hence, half the values are discarded. It should be:

for ev := range ch {
        evtList = append(evtList, ev)
        count++
}

In order to actually utilize the values read in the loop iterator.

Ranging over channels is demonstrated in the Tour of Go and detailed in the Go spec.