Channel Directions in Crystal
Channel directions in Crystal can be specified using the Channel(T).send
and Channel(T).receive
types. This specificity increases the type-safety of the program.
# This `ping` function only accepts a channel for sending
# values. It would be a compile-time error to try to
# receive on this channel.
def ping(pings : Channel(String).send, msg : String)
pings.send msg
end
# The `pong` function accepts one channel for receives
# (`pings`) and a second for sends (`pongs`).
def pong(pings : Channel(String).receive, pongs : Channel(String).send)
msg = pings.receive
pongs.send msg
end
def main
pings = Channel(String).new(1)
pongs = Channel(String).new(1)
spawn { ping(pings, "passed message") }
spawn { pong(pings, pongs) }
puts pongs.receive
end
main
To run the program:
$ crystal channel_directions.cr
passed message
In Crystal, channels are used for communication between fibers (lightweight threads). The Channel(T).send
and Channel(T).receive
types are used to specify the direction of the channel.
The ping
function takes a send-only channel (Channel(String).send
) and a message. It sends the message on the channel.
The pong
function takes a receive-only channel (Channel(String).receive
) and a send-only channel (Channel(String).send
). It receives a message from the first channel and sends it on the second channel.
In the main
function, we create two buffered channels with a capacity of 1. We then spawn two fibers: one for ping
and one for pong
. Finally, we print the message received from the pongs
channel.
Crystal’s channel system is similar to the one in the original example, allowing for safe concurrent communication between fibers.