To unbuffered channel with one goroutine: No (Why: by design):
You may use Buffered channel with one goroutine or
two goroutines using unbuffered channel to avoid deadlock:
If the channel is unbuffered, the sender blocks until the receiver has
received the value. If the channel has a buffer, the sender blocks
only until the value has been copied to the buffer; if the buffer is
full, this means waiting until some receiver has retrieved a value.
1- Using buffered channel: The main itself is a goroutine and if you need do it in one goroutine you should use buffered channel like this:
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan int, 1)
for {
select {
case ch1 <- 1:
fmt.Println("sent 1 ")
case c := <-ch1:
fmt.Println(" received ", c)
}
time.Sleep(time.Second)
}
}
output:
sent 1
received 1
sent 1
received 1
sent 1
received 1
2- Using unbuffered channel: You may send and receive to unbuffered channel in two case statements in one select, and you need two goroutines here, see:
Try this:
package main
import (
"fmt"
"time"
)
func main() {
go ct("Alex")
go ct("John")
//select {}
time.Sleep(300 * time.Millisecond)
}
func ct(name string) {
for {
select {
case ch1 <- 1:
fmt.Println(name, "sent 1")
case c := <-ch1:
fmt.Println(name, "received:", c)
}
fmt.Println(name, "waiting...")
time.Sleep(100 * time.Millisecond)
}
}
var ch1 = make(chan int)
output:
John sent 1
John waiting...
Alex received: 1
Alex waiting...
John received: 1
John waiting...
Alex sent 1
Alex waiting...
John sent 1
John waiting...
Alex received: 1
Alex waiting...