繁体   English   中英

尝试使用 dyn AsyncReadExt,“无法将特征制成对象”错误

[英]trying to use dyn AsyncReadExt, “the trait cannot be made into an object” error

我正在开发一个网络服务,该服务旨在与 TcpStream 或 stdin/stdout 一起使用。 我收到一个编译错误: the trait tokio::io::util::async_read_ext::AsyncReadExt cannot be made into an object 目前我的解决方法是使用包装枚举:

enum ClientReader {
    Stream(OwnedReadHalf),
    Stdin(Stdin),
}

enum ClientWriter {
    Stream(OwnedWriteHalf),
    Stdout(Stdout),
}

这需要到处都是match块,这看起来很不雅观。

我做了一个简化的项目来重现这个问题:

Cargo.toml

[package]
name = "demo"
version = "0.1.0"
authors = ["test"]
edition = "2018"

[dependencies]
tokio = { version = "0.2", features = ["full"] }

src/main.rs

use tokio::io::AsyncReadExt;

struct Test {
  test: Box<dyn AsyncReadExt>,
}

fn main () {}

这会产生类似的错误:

error[E0038]: the trait `tokio::io::AsyncReadExt` cannot be made into an object
    --> src/main.rs:4:3
     |
4    |   test: Box<dyn AsyncReadExt>,
     |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `tokio::io::AsyncReadExt` cannot be made into an object
     |
    ::: /home/???/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.2.22/src/io/util/async_read_ext.rs:162:12
     |
162  |         fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
     |            ---- the trait cannot be made into an object because method `read` references the `Self` type in its return type
...
280  |         fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
     |            ---------- the trait cannot be made into an object because method `read_exact` references the `Self` type in its return type

我不知道如何继续。 我正在考虑为enum包装器使用一个巨大的impl块,但这似乎比match块更多的工作。 在 OO 语言中会有一个父类或接口,所以我研究了trait_enum crate 来自动制作包装器impl但在trait_enum工作时遇到了很多麻烦。

目前,我确信唯一的清理工作是将解决方法移动到宏或函数中。

我很感激任何关于更好的方法来做到这一点的反馈。 :)

编辑:根据 user4815162342 的建议,我在 AsyncReadExt 类型上AsyncReadExt了结构泛型,这似乎适用于我的示例。 稍后将尝试我的更大项目。

use tokio::io::AsyncReadExt;

struct Test<T: AsyncReadExt> {
  test: T,
}

async fn myfn<T: AsyncReadExt>(mut t: Test<T>) where T: std::marker::Unpin {
    let mut v = Vec::<u8>::new();
    t.test.read_buf(&mut v).await;
}

fn main () {}

要将AsyncRead转换为 trait 对象,您应该使用Pin<Box<dyn AsyncRead>>

use std::pin::Pin;
use tokio::io::AsyncRead;

struct Test {
    test: Pin<Box<dyn AsyncRead>>,
}

impl Test {
    fn new<T: AsyncRead>(io: T) -> Self {
        Self {
            test: Box::pin(io),
        }
    }
}

AsyncReadExt特点是扩展特性,你应该总是使用AsyncRead提的类型时特质AsyncRead

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM