TL; DR: вы не используете оператор ?
.
Поскольку вы не предоставили один , вот MCVE вашей проблемы.Обратите внимание, что мы не знаем , какой тип ошибки у вашей serialize_addr
функции, поэтому мне пришлось что-то выбрать:
use futures::Future;
use std::{io, net::SocketAddr};
use tokio::{io::write_all, net::TcpStream};
fn serialize_addr() -> Result<Vec<u8>, Box<dyn std::error::Error>> {
Ok(vec![])
}
pub fn handle_client(addr: &SocketAddr) -> impl Future<Item = (), Error = io::Error> {
TcpStream::connect(addr).and_then(|stream| {
let addr = serialize_addr()?;
write_all(stream, addr).then(|_result| Ok(()))
})
}
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--> src/lib.rs:11:20
|
11 | let addr = serialize_addr()?;
| ^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `futures::future::then::Then<tokio_io::io::write_all::WriteAll<tokio_tcp::stream::TcpStream, std::vec::Vec<u8>>, std::result::Result<(), std::io::Error>, [closure@src/lib.rs:12:38: 14:10]>`
|
= help: the trait `std::ops::Try` is not implemented for `futures::future::then::Then<tokio_io::io::write_all::WriteAll<tokio_tcp::stream::TcpStream, std::vec::Vec<u8>>, std::result::Result<(), std::io::Error>, [closure@src/lib.rs:12:38: 14:10]>`
= note: required by `std::ops::Try::from_error`
Поскольку в сообщении об ошибке говорится:
оператор ?
можно использовать только в функции, которая возвращает Result
или Option
(или другой тип, который реализует std::ops::Try
)
и
не может использовать оператор ?
в функции, которая возвращает Then<WriteAll<TcpStream, Vec<u8>>, Result<(), io::Error>, [closure]>
Вместо этого используйте тот факт, что Result
можно рассматривать как будущее, и позвольте емуучаствовать в цепочке функций.
Кроме того, как и везде в Rust, вам нужен унифицированный тип ошибки.Я выбрал Box<dyn Error>
для простоты.Это может быть достигнуто с помощью map_err
и Into::into
use futures::Future;
use std::net::SocketAddr;
use tokio::{io::write_all, net::TcpStream};
type Error = Box<dyn std::error::Error>;
fn serialize_addr() -> Result<Vec<u8>, Error> {
Ok(vec![])
}
pub fn handle_client(addr: &SocketAddr) -> impl Future<Item = (), Error = Error> {
TcpStream::connect(addr)
.map_err(Into::into)
.and_then(|stream| serialize_addr().map(|addr| (stream, addr)))
.and_then(|(stream, addr)| write_all(stream, addr).map_err(Into::into))
.then(|_result| Ok(()))
}
В будущем синтаксис async
/ await
облегчит этоследовать.