Конец канала в Rust
Конец наступает, когда исчезает последний отправитель и в очереди не осталось непрочитанных значений. Следующий прием возвращает ошибку: это сигнал, что новых данных уже не будет, а не сбой в переданных числах.
Прочитаем все, что лежит в очереди, затем уничтожим отправителя и проверим прием:
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::channel();
match tx.send(9) {
Ok(()) => {}
Err(_) => {}
}
match rx.recv() {
Ok(v) => println!("got {}", v),
Err(_) => {}
}
drop(tx);
match rx.recv() {
Ok(v) => println!("more {}", v),
Err(_) => println!("closed"),
}
}
Первый прием забирает 9. После
уничтожения отправителя очередь пуста,
поэтому второй прием печатает closed
через вариант ошибки.
Тот же сценарий удобно пройти в цикле: успех означает очередное число, ошибка останавливает обход:
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::channel();
match tx.send(1) {
Ok(()) => {}
Err(_) => {}
}
match tx.send(2) {
Ok(()) => {}
Err(_) => {}
}
drop(tx);
loop {
match rx.recv() {
Ok(v) => println!("{}", v),
Err(_) => break,
}
}
}
Дано число:
let num = 6;
Передайте число, заберите его, затем
освободите отправителя и еще раз
обратитесь к приемнику. Выведите
done при ошибке второго приема.
Закрытие:
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::channel();
drop(tx);
match rx.recv() {
Ok(v) => println!("{}", v),
Err(_) => println!("end"),
}
}
Запустите фрагмент и скажите, что напечатается и почему в очереди не было ни одного значения.
Скажите, почему ошибка приема после конца канала не означает, что последнее полученное число было повреждено.