[英]Proper way in Rust to store a reference in a struct
What is the proper way to store a reference in a struct and operate on it given this example:在这个例子中,将引用存储在结构中并对其进行操作的正确方法是什么:
// Trait that cannot be changed
pub trait FooTrait {
pub fn open(&self, client: &SomeType);
pub fn close(&self);
}
pub struct Foo {
// HOW TO STORE IT HERE???
// client: &SomeType,
}
impl FooTrait for Foo {
pub fn open(&self, client: &SomeType) {
// HOW TO SAVE IT HERE?
// NOTE that &self cannot be changed into &mut self because the trait cannot be modified
// smth like self.client = client;
}
pub fn close(&self) {
// HOW TO DELETE IT HERE?
// NOTE that &self cannot be changed into &mut self because the trait cannot be modified
}
}
Is there a design pattern that could fit to my snippet?是否有适合我的代码片段的设计模式?
This is horribly complicated on its surface because of lifetime issues.由于寿命问题,这在表面上非常复杂。 Rust is designed to guarantee memory safety, but this pattern creates an untenable situation where the caller of
FooTrait::open()
needs some way to tell Rust that the client
borrow will outlive *self
. Rust 旨在保证 memory 的安全,但这种模式造成了一种难以维持的情况,即
FooTrait::open()
的调用者需要某种方式来告诉 Rust client
借用的时间将超过*self
。 If it can't do that, Rust will disallow the method call.如果它不能这样做,Rust 将不允许该方法调用。 Actually making this work with references is probably not feasible, as
Foo
needs a lifetime parameter, but the code that creates the Foo
may not know the appropriate lifetime parameter.实际上,使用引用进行这项工作可能是不可行的,因为
Foo
需要一个生命周期参数,但创建Foo
的代码可能不知道合适的生命周期参数。
You can make this pattern work by combining a few things, but only if you can modify the trait.你可以通过组合一些东西来使这个模式起作用,但前提是你可以修改特征。 If you can't change the definition of the trait, then what you are asking is impossible.
如果您不能更改特征的定义,那么您所要求的是不可能的。
Option
so that close
can clear the value.Option
以便close
可以清除该值。Cell
) to allow mutating self.client
even if self
is a shared reference.Cell
)以允许改变self.client
即使self
是共享引用。Rc
or Arc
, for example.Rc
或Arc
。 These types sidestep the lifetime issue entirely.Borrow<T>
to support them all at once.Borrow<T>
上通用以同时支持它们。use std::cell::Cell;
use std::borrow::Borrow;
pub trait FooTrait {
fn open(&self, client: impl Borrow<SomeType> + 'static);
fn close(&self);
}
pub struct SomeType;
pub struct Foo {
client: Cell<Option<Box<dyn Borrow<SomeType>>>>,
}
impl FooTrait for Foo {
fn open(&self, client: impl Borrow<SomeType> + 'static) {
self.client.set(Some(Box::new(client)));
}
fn close(&self) {
self.client.set(None);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.