我有一个包装了Box<dyn Any>个构造函数的VEC的 struct ,我已经断言它是克隆的.

我有一个性状Ctor,它采用克隆逻辑,产生另一个Box<dyn Ctor>.如果我不实现特征,或者如果我不调用克隆函数,它编译得很好.

但是如果我同时执行这两种操作,我会收到一条奇怪的消息,声称数据超出了它的生命周期界限,尽管我断言该值为'static.

(代码比上面的描述更容易阅读,但如果你的帖子中没有足够的英文文本,Stackoverflow会抱怨,如果你在Stackoverflow帖子中放入lorem ipsum,挑剔的人会抱怨)

取消注释下面的任一块可以很好地编译,但同时取消注释两个块会导致错误:

use std::any::Any;

// pub struct SVConstructor {
//     ctors: Vec<Box<dyn Ctor + 'static>>,
// }

// impl Clone for SVConstructor {
//     fn clone(&self) -> Self {
//         let Self { ctors } = self;
//         let mut new_ctors: Vec<Box<dyn Ctor + 'static>> = Vec::new();
//         for ctor in ctors {
//             let value: Box<dyn Ctor + 'static> = ctor.clone_box();
//             drop(ctor);
//             new_ctors.push(value);
//         }
//         Self { ctors: new_ctors }
//     }
// }

pub trait Ctor: Fn() -> Box<dyn Any + Send + Sync + 'static> + Send + Sync {
    fn clone_box(&self) -> Box<dyn Ctor + 'static>;
}

// impl<T: Fn() -> Box<dyn Any + Send + Sync + 'static> + Send + Sync + Clone + 'static> Ctor for T {
//     fn clone_box(&self) -> Box<dyn Ctor + 'static> {
//         Box::new(self.clone())
//     }
// }

当我取消对我得到的一切的 comments 时:

error[E0521]: borrowed data escapes outside of associated function
  --> src/lib.rs:12:50
   |
8  |     fn clone(&self) -> Self {
   |              -----
   |              |
   |              `self` is a reference that is only valid in the associated function body
   |              let's call the lifetime of this reference `'1`
...
12 |             let value: Box<dyn Ctor + 'static> = ctor.clone_box();
   |                                                  ^^^^^^^^^^^^^^^^
   |                                                  |
   |                                                  `self` escapes the associated function body here
   |                                                  argument requires that `'1` must outlive `'static`

For more information about this error, try `rustc --explain E0521`.

推荐答案

问题是,ctors在for循环中是&Vec<Box<dyn Ctor + 'static>>类型的,&Box<dyn Ctor + 'static>还实现了Fn() -> Box<dyn Any + Send + Sync> + Send + Sync(Box<F> and &F实现了相同的Fn特征)和Clone(所有引用都是Copy),所以您使用&Box<dyn Ctor + 'static>中的T来调用clone_box,这会导致您复制引用及其生存期,而不是复制Box中的Ctor.解决办法是go 掉多余的引用:

impl Clone for SVConstructor {
    fn clone(&self) -> Self {
        let Self { ctors } = self;
        let mut new_ctors: Vec<Box<dyn Ctor + 'static>> = Vec::new();
        for ctor in ctors {
            let value: Box<dyn Ctor + 'static> = (*ctor).clone_box();
            new_ctors.push(value);
        }
        Self { ctors: new_ctors }
    }
}

Because ctor is only a reference the drop(ctor) doesn't do anything either so you can remove it as well.
Playground

Rust相关问答推荐

即使参数和结果具有相同类型,fn的TypId也会不同

有条件默认实现

重新导出proc宏导致未解决的extern crate错误""

展开枚举变量并返回所属值或引用

我应该将哪些文件放入我的GitHub存储库

Rust 的多态现象.AsRef与Derf

为什么TcpListener的文件描述符和生成的TcpStream不同?

将一个泛型类型转换为另一个泛型类型

Rust中WPARAM和VIRTUAL_KEY的比较

如何执行数组文字的编译时串联?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

Rust Option 的空显式泛型参数

Rust FFI 和 CUDA C 性能差异

如何在 Rust 中将函数项变成函数指针

Rust Redis 中的 HSET 命令问题

为什么 `tokio::join!` 宏不需要 Rust 中的 `await` 关键字?

如何创建递归borrow 其父/创建者的 struct ?

为什么在 rust 中删除 vec 之前应该删除元素

有没有办法阻止 rust-analyzer 使非活动代码变暗?

将 reqwest bytes_stream 复制到 tokio 文件中