Introduction
In Rust, Receiver is a type used to receive messages from a channel. It is part of the standard library's std::sync::mpsc module, where mpsc stands for "multiple producer, single consumer." Channels provide a way for different parts of your code to communicate with each other, especially in concurrent programming. The Receiver is used to read messages sent by the corresponding Sender.
Using Receiver
To use Receiver, you need to create a channel using the std::sync::mpsc::channel function, which returns a (Sender, Receiver) pair. You can then use the Receiver to receive messages sent through the channel.
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send("Hello from the spawned thread!").unwrap();
    });
    let received = rx.recv().unwrap();
    println!("Received: {}", received);
}
// Output:
// Received: Hello from the spawned thread!
Key Methods
Below are some of the key methods exposed by the Receiver class:
recv
Blocks the current thread until a message is available and returns it. If the channel is closed, it returns an Err.
use std::sync::mpsc;
use std::thread;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send(42).unwrap();
    });
    let received = rx.recv().unwrap();
    println!("Received: {}", received);
}
// Output:
// Received: 42
try_recv
Tries to receive a message from the channel without blocking. It returns immediately with a Result, which is Ok(T) if a message is available, or Err(TryRecvError) if the channel is empty or closed.
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send(42).unwrap();
    });
    thread::sleep(Duration::from_millis(100));
    match rx.try_recv() {
        Ok(received) => println!("Received: {}", received),
        Err(e) => println!("Failed to receive: {:?}", e),
    }
}
// Output:
// Received: 42
iter
Returns an iterator that will yield messages received from the channel. The iterator ends when the channel is closed and all messages have been received.
use std::sync::mpsc;
use std::thread;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        for i in 0..5 {
            tx.send(i).unwrap();
        }
    });
    for received in rx.iter() {
        println!("Received: {}", received);
    }
}
// Output:
// Received: 0
// Received: 1
// Received: 2
// Received: 3
// Received: 4
Example Usage
Example 1: Basic Usage
use std::sync::mpsc;
use std::thread;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send("Hello from the spawned thread!").unwrap();
    });
    let received = rx.recv().unwrap();
    println!("Received: {}", received);
}
// Output:
// Received: Hello from the spawned thread!
Example 2: Receiving Multiple Messages
use std::sync::mpsc;
use std::thread;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send(1).unwrap();
        tx.send(2).unwrap();
        tx.send(3).unwrap();
    });
    for _ in 0..3 {
        let received = rx.recv().unwrap();
        println!("Received: {}", received);
    }
}
// Output:
// Received: 1
// Received: 2
// Received: 3
Example 3: Non-blocking Receive
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        thread::sleep(Duration::from_millis(50));
        tx.send(42).unwrap();
    });
    match rx.try_recv() {
        Ok(received) => println!("Received: {}", received),
        Err(e) => println!("Failed to receive: {:?}", e),
    }
    thread::sleep(Duration::from_millis(100));
    match rx.try_recv() {
        Ok(received) => println!("Received: {}", received),
        Err(e) => println!("Failed to receive: {:?}", e),
    }
}
// Output:
// Failed to receive: Empty
// Received: 42
Example 4: Iterating Over Messages
use std::sync::mpsc;
use std::thread;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        for i in 0..5 {
            tx.send(i).unwrap();
        }
    });
    for received in rx.iter() {
        println!("Received: {}", received);
    }
}
// Output:
// Received: 0
// Received: 1
// Received: 2
// Received: 3
// Received: 4
Example 5: Handling Channel Closure
use std::sync::mpsc;
use std::thread;
fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send(1).unwrap();
        // Dropping the sender to close the channel
        drop(tx);
    });
    loop {
        match rx.recv() {
            Ok(received) => println!("Received: {}", received),
            Err(_) => {
                println!("Channel closed");
                break;
            }
        }
    }
}
// Output:
// Received: 1
// Channel closed
Considerations
- Channels provide a powerful way to communicate between threads, but they can introduce complexity and potential for deadlocks if not managed carefully.
 - Always handle the 
Resultreturned byrecvandtry_recvto manage possible errors when the channel is closed. - Dropping the 
Senderwill close the channel, causingrecvto return an error once all messages have been received. 
See Also
- Sender - The sending half of a channel used to send messages.
 - JoinHandle - A handle for managing the lifecycle of a thread.
 - Mutex - A mutual exclusion primitive for protecting shared data.
 
