- 此问题在此处已有答案**:
Why are trait methods with generic type parameters object-unsafe?(2个答案)
6天前关闭。
我有这个签名,我想用在一个特质,以创建许多适配器(文件系统,aws,谷歌云等)。
我尝试创建下面的Trait
,但出现此错误:
use tokio::io::AsyncRead;
#[async_trait::async_trait]
pub trait Trait: Send + Sync {
async fn put_file<S>(&self, filename: &str, stream: S) -> Result<()>
where
S: AsyncRead + Send;
}
pub struct Client {
location: String,
}
#[async_trait::async_trait]
impl Trait for Client {
async fn put_file<S>(&self, filename: &str, stream: S) -> Result<()>
where
S: AsyncRead + Send,
{
futures::pin_mut!(stream);
let path = Path::new(&self.location).join(filename);
let mut file = BufWriter::new(File::create(path).await?);
tokio::io::copy(&mut stream, &mut file).await?;
Ok(())
}
}
error[E0038]: the trait `Trait` cannot be made into an object
|
23 | pub client: Arc<dyn Trait>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
5 | pub trait Trait: Send + Sync {
| ----- this trait cannot be made into an object...
6 | async fn put_file<S>(&self, filename: &str, stream: S) -> Result<()>
| ^^^^^^^^ ...because method `put_file` has generic type parameters
= help: consider moving `put_file` to another trait
为什么?
1条答案
按热度按时间2hh7jdfx1#
如果您阅读错误消息,它会提到
...因为方法
put_file
具有泛型类型参数以及您可以在何处找到有关对象安全性的更多信息
你可以不创建trait对象:
或者全程使用动态调度: