Channel Directions in Rust
In Rust, we can specify whether a channel is for sending or receiving values when using them as function parameters. This specificity increases the type-safety of the program.
use std::sync::mpsc;
// This `ping` function only accepts a channel for sending
// values. It would be a compile-time error to try to
// receive on this channel.
fn ping(pings: &mpsc::Sender<String>, msg: String) {
pings.send(msg).unwrap();
}
// The `pong` function accepts one channel for receives
// (`pings`) and a second for sends (`pongs`).
fn pong(pings: &mpsc::Receiver<String>, pongs: &mpsc::Sender<String>) {
let msg = pings.recv().unwrap();
pongs.send(msg).unwrap();
}
fn main() {
let (pings_tx, pings_rx) = mpsc::channel();
let (pongs_tx, pongs_rx) = mpsc::channel();
ping(&pings_tx, String::from("passed message"));
pong(&pings_rx, &pongs_tx);
println!("{}", pongs_rx.recv().unwrap());
}
To run the program:
$ cargo run
passed message
In this Rust version, we use the std::sync::mpsc
module to create channels. The Sender
and Receiver
types are used to specify the direction of the channel.
The ping
function takes a &Sender<String>
, which can only send values. The pong
function takes a &Receiver<String>
for receiving and a &Sender<String>
for sending.
In the main
function, we create two channels using mpsc::channel()
. We then pass the appropriate senders and receivers to our functions.
This approach ensures type safety at compile-time, preventing misuse of the channels.