I found the code snippet below on a tech talk, I am a little bit confused about one thing.
Should table <- new(Ball)
be placed before go player("ping", table)
?
And why do we even need table <- new(Ball)
? I think table := make(chan *Ball)
already creates the channel. Has this something to do with deadlocks?
type Ball struct { hits int }
fun main() {
table := make(chan *Ball)
go player("ping", table)
go player("pong", table)
table <- new(Ball) // game on; toss the ball
time.Sleep(1*time.Second)
<-table // game over; grab the ball
}
func player(name string, table chan *Ball)
for {
ball := <-table
ball.hits++
fmt.println(name, ball.hits)
time.Sleep(100 * time.Millisecond)
table <- ball
}
}
The <-
operator is what places something in the channel, or takes it out. The side it's on shows you if it's being placed in, or taken out. Because the channel doesn't have a size it cannot actually "hold" and item, it makes the go
funcs block until there is something put in the channel. Both sides (insert and remove) block on a channel with no size, so if you try to insert something when there is no receiver, it blocks until there is one. In this specific code, the player
func then removes it <- table
and places it back in table <-
.
As to your question regarding moving table <- new(Ball)
. If you try to send the ball without a receiver, main blocks waiting for something to take the ball. A channel without a size is more like "handing" off objects because there is no storage involved. If, instead, it was created with a buffer size e.g. table := make(chan *Ball, 1)
, then it only blocks (the same as before) when it already has 1 item in it. So if you created it with a buffer of one, but tried to place 2 balls in it before the go
funcs, it would deadlock same as before.