golang / tour

[mirror] A Tour of Go
BSD 3-Clause "New" or "Revised" License
1.53k stars 521 forks source link

[Report] - INCORRECT information : The theory is seriously wrong #1478

Open ngochd7 opened 1 year ago

ngochd7 commented 1 year ago

Context: https://go.dev/tour/concurrency/4

I found the following content that you provided is not correct: The loop for i := range c receives values from the channel repeatedly until it is closed

It’s possible to close a non-empty channel but still have the remaining values be received. This means: the For loop will NOT stop even if the Channel is closed. Here is an example code:

package main

import "fmt"

func main() {

    queue := make(chan string, 3)
    queue <- "one"
    queue <- "two"
    queue <- "three"
    close(queue)

    for elem := range queue {
        fmt.Println(elem)
    }
}

Output:

one
two
three
crisman commented 1 year ago

Notice in the slide text (on the left):

ok is false if there are no more values to receive and the channel is closed.

close() does not destroy all data in a channel, it marks it to say no more values will be sent on the channel.

See also: https://go.dev/ref/spec#Close

ngochd7 commented 1 year ago

Yes, I agree with you, but I am raising the problem of For loop with Channel.

Different ways of using Channels solve different problems:

crisman commented 1 year ago

I am no longer sure what you are reporting. Could you rephrase the issue?

ngochd7 commented 1 year ago

The problem is that you are not correctly expressing the end time of the For loop. I think I detailed it in the first comment, please read it again carefully :333

crisman commented 1 year ago

The spec on this is https://go.dev/ref/spec#For_range :

  1. For channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever.

In the slide, does this seem to answer your issue?

Before:

The loop for i := range c receives values from the channel repeatedly until it is closed.

After:

The loop for i := range c receives values from the channel repeatedly for all values sent before it is closed.

Do you see a better phrasing?

ngochd7 commented 1 year ago

I think you should separate them so others can see 2 things: (Don't just use 1 sentence to describe as you mentioned above)

  1. They can use the For syntax to get the messages out of the Channel
  2. Using the For syntax will allow them to continue to retrieve messages that are still present in the Channel even after the Channel is closed.

It would be great if you have a detailed description of the differences of the 3 syntaxes:

crisman commented 1 year ago

For is not unique in allowing channel receive after a close. Close does not remove items from a channel, nor does it stop anyone from receiving them.

To quote the slide:

A sender can close a channel to indicate that no more values will be sent.

Those three options seem to me to be covered already.