title: Go channels unbuffered
body: <pre><code>package main 
  import (
      "fmt"
      "time"
  )
  
  var message chan string
  
  func main() {
      message = make(chan string)
      count := 6
      flag := "first"
      go func() {
          fmt.Println("child go ",flag)
          for i := 0; i &lt; count; i++ {
              fmt.Println("set:",i)
              message &lt;- fmt.Sprintf("message %d",i)
          }   
      }()
  
      time.Sleep(time.Second * 0)
  
      fmt.Println("main thread ",flag)
      flag = "last"
      for i := 0 ; i &lt; count; i++ {
          fmt.Println("get:",i)
          fmt.Println(&lt;-message)
      }
  }
  </code></pre>
  
  <p>I run the code and the result is:</p>
  
  <pre><code>main thread  first
  get: 0
  child go  last
  set: 0
  set: 1
  message 0
  get: 1
  message 1
  get: 2
  set: 2
  set: 3
  message 2
  get: 3
  message 3
  get: 4
  set: 4
  set: 5
  message 4
  get: 5
  message 5
  </code></pre>
  
  <p>I am confused by the result. Why does 'message 1' appear after 'get 1' but not 'set 2'? This has puzzled me for several days!</p>
  
  <p>I think when it 'get 1', the main go routine should be blocked and the child go routine should be exec'd, send 'message 1' to channel message and continue the for loop and print 'set 2',thus blocked at send 'message 2' to channel, so main go routine start to run, output 'message 1'.</p>