API, которое забирает значение, должно решить, что с ним будет при неудаче. String::from_utf8 принимает Vec<u8> по значению, и при ошибке им владеет сама ошибка.
fn main() {
let bytes = vec![b'o', b'k', 0xff, b'!'];
match String::from_utf8(bytes) {
Ok(s) => println!("{s}"),
Err(e) => {
let at = e.utf8_error().valid_up_to();
let bytes = e.into_bytes();
println!("bad byte at {at}, {} bytes back", bytes.len());
}
}
}
Вывод bad byte at 2, 4 bytes back. Без копирования, вызывающий получает свой буфер и смещение одним значением. mpsc::Sender::send поступает так же, SendError несёт сообщение, которое не удалось доставить.
Альтернатива - ошибка, которая только описывает сбой, и тогда значение уничтожается внутри вызова. Для маленького значения это нормально. Для большого буфера вызывающему остаётся либо клонировать перед каждой попыткой, либо терять данные на пути ошибки, и ни то ни другое не видно в сигнатуре.
Какие ещё API стандартной библиотеки забирают значение и выбрасывают его при ошибке? Короткий список помог бы сверить с ним собственные интерфейсы.