Используйте динамически типизированный объект, реализующий `tokio :: io :: AsyncWrite` - PullRequest
0 голосов
/ 11 июля 2019

Я довольно новичок в Rust, так что, возможно, я упускаю что-то очевидное.

Этот код отлично работает:

pub fn say_hello() {
    let fut = tokio::io::write_all(tokio::io::stdout, "Hello, world!").then(|_| {});
    tokio::run(fut);
}

Принимая во внимание, что следующий код не компилируется:

pub fn say_hello(w: Box<dyn tokio::io::AsyncWrite>) {
    let fut = tokio::io::write_all(w, "Hello, world!").then(|_| {});
    tokio::run(fut);
}

Ошибка компилятора:

error[E0277]: `dyn tokio_io::async_write::AsyncWrite` cannot be sent between threads safely

Есть ли способ выполнить то, что я хочу (на самом деле динамическая диспетчеризация, а не просто сделать функцию универсальной).

1 Ответ

1 голос
/ 11 июля 2019

TL; DR tokio::run expects Будущее, которое реализует Send, а также 'static срок службы.

Если вы добавите необходимые ограничения к вашему параметру, он будет работать так же, как Stdout:

pub fn say_hello(w: Box<dyn tokio::io::AsyncWrite + Send + 'static>) {
    let fut = tokio::io::write_all(w, "Hello, world!").then(|_| Ok(()));

    tokio::run(fut);
}

Примечание: Stdout работает, потому что Реализации Stdout уже содержат Send, и это собственные данные для охватывающей области.


Но как Rust может узнать, что Future, созданный write_all, Send или нет?

Вызов write_all с реализацией AsyncWrite - это нормально, поскольку tokio :: io :: write_all ожидает реализации AsyncWrite. Но tokio :: run ожидает, что принадлежит или 'static Future, который реализует Send

Вы пытаетесь запустить WriteAll future, но, пожалуйста, отметьте эту Send реализацию на WriteAll, она реализует Send только тогда, когда T и A реализуют Send. В вашем случае T - это тип вашего буфера, который &'static str, он реализует Send, а A - реализацию AsyncWrite.

В этом определении нет заявления о том, что w является Send (или имеет 'static / , принадлежащий время жизни):

pub fn say_hello(w: Box<dyn tokio::io::AsyncWrite>) 

Вот почему Tokio Run не принимает WriteAll Future.

...