for循环和select和select的区别是什么?

Could not fully understand it from the docs or google:

What are the differences between the two and in Which case would you use each one?

    for{
       select{
       case s := <-something:
           fmt.Println(s)
       case done := <-true:
           return 
       }
    }

and

       select{
       case s := <-something:
           fmt.Println(s)
       case done := <-true:
           return 
       }

Thanks

Code with loop will keep printing data from channel something until it receives anything on channel done.

Select-only code will either print data from channel something or will quit when it receives anything on channel done. Only one case will be executed. Keep in mind there is no fallthrough in Go select and switch statements by default.

If your program sends data to the 'something' channel a bunch of times you are going to want to repeat the select clause until you receive a done signal.

For example imagine you are running the following routine

.... (some calculations)
something <- x 
.... (some calculations)
something <- y
true <- z 

If your routine doesn't have the for loop it will only receive the value 'x' and won't receive y or z.

select statement executes through its cases (sending/receiving a the channel) once. If none of its cases are ready to be executed, it blocks until at least one of the case is ready to execute. If more than one cases are ready at the same time, one of the ready case is selected to be executed at random.

So in second case, if there is some data on the something channel, it would be read and put into s. But there is also a chance of true being sent on done while the case s := <-something: will never be executed.

In the first case, you probably want something like this (also in second case):

for{
   select{
   case s := <-something:
       fmt.Println(s)
   case <-done: // note the difference
       return 
   }
}

What this now does is that it waits for data on something and also keeps an eye on done. If there is data on something channel (and no data on done), it will be read and put into s (case branch case s := <-something: will be executed with s having the value read from something). This will account for one full execution of select statement and the control will go back to for loop and it will start over again.

If there is no data on something channel, select blocks and waits for data on either something or done. If data arrives on something, similar execution as above happens, otherwise if it arrives in done, the function returns (breaks out of loop). This way some other process can write to done and signal the function containing above for loop to stop processing something and return.