rust - 具有特征的寿命和所有权
问题描述
我正在构建一个 Rocket 应用程序,并希望它为我管理一些对象。为此,它们需要是Send
和Sync
。这是一个最小的人为示例,显示了我遇到的错误(Playground):
trait MyTrait {
fn foo(&self) {}
}
struct TraitThing {}
impl MyTrait for TraitThing {
fn foo(&self) {
println!("Foo!");
}
}
struct Thing {
tt: &'static (dyn MyTrait + Send + Sync),
}
impl Thing {
fn with_trait(tt: &'static (dyn MyTrait + Send + Sync)) -> Self {
Self { tt }
}
}
fn main() {
let tt = TraitThing {};
let thing = Thing::with_trait(&tt);
thing.tt.foo();
}
我可能不明白'static
. 理想情况下,我想Thing
拥有tt
,但据我所知,由于我的 TraitThing 不是Sized
(并且可能永远不会是),它不能是一个特征对象,所以它必须通过引用传递。
那么,如何在保留Send
andSync
特征的同时解决这个问题呢?
谢谢!
附加说明:我在 Rust 书和其他地方阅读了很多关于生命周期和特征的内容,但我希望能进一步阅读材料。
解决方案
您可以使用Box,但它会分配给堆并使用动态调度,这在您的情况下没有用。当您想要实现类似 Trait 的不同类型的列表时,它很有用,例如:
struct Thing {
tt: Vec<Box<dyn MyTrait + Send + Sync>>,
}
但是在您的情况下,您只有一个元素,因此您可以在此设置中使用泛型:
trait MyTrait {
fn foo(&self) {}
}
struct TraitThing {}
impl MyTrait for TraitThing {
fn foo(&self) {
println!("Foo!");
}
}
struct Thing<T>
where
T: MyTrait + Send + Sync
{
tt: T,
}
impl<T> Thing<T>
where
T: MyTrait + Send + Sync
{
fn with_trait(tt: T) -> Self {
Self { tt }
}
}
fn main() {
let tt = TraitThing {};
let thing = Thing::with_trait(tt);
thing.tt.foo();
}
推荐阅读
- java - Java - 使用执行器服务的线程
- python - Python 列表理解:如何操作文件中的文本
- javascript - Electron-fetch 将 json 作为 [object object] 返回,但网络控制台显示返回的正确 json 对象
- python - 在 Python 文档中保持别名类型简单?
- angular - 如何将路由器链接添加到 Angular 8 上的按钮单击功能?
- python - python KeyError:'sapi5'
- c# - xamarin 表单中具有隔离进程的后台服务
- c++ - 在 C++ 中添加两个表示数字的字符串
- c - 将浮点数分解为整数部分和小数部分
- java - 为什么 LWJGL (OpenGL) drawElements 不绘制?