我们知道,很容易将RefCell<T>类型的值转换为&T类型的值,以便作为函数中的参数使用:
fn main() {
let a: RefCell<i32> = RefCell::new(0);
my_func(a.borrow().deref());
}
fn my_func(i: &i32) {}在我的场景中,RefCell被存储在HashMap中,因此它们被包装在Option中。我还希望传递给它们的函数有选项的概念,但我只想传递不可变的引用,而不是整个RefCell。我们可以这样做:
fn main() {
let a: Option<RefCell<i32>> = Some(RefCell::new(0));
match a {
Some(ref_cell) => my_func(Some(ref_cell.borrow().deref())),
None => my_func(None)
};
}
fn my_func(i: Option<&i32>) {}这是可行的,但在我的特定场景中,my_func将其中几个Option<&T>作为参数,因此这样做意味着match对每个参数嵌套,并以指数方式增长。因此,有办法这样做是有帮助的:
fn main() {
let a: Option<RefCell<i32>> = Some(RefCell::new(0));
let c = match a {
Some(ref_cell) => Some(ref_cell.borrow().deref()), // won't compile as this borrow won't live long enough
None => None
};
my_func(c);
}
fn my_func(i: Option<&i32>) {}因此,本质上,我希望能够从Option<RefCell<T>>转换为Option<&T>。我觉得这是可能的,但我想不出办法。我总是遇到一些在.borrow()上执行RefCell的问题,但是它的寿命不够长。
发布于 2022-03-14 00:46:07
您可以使用Option上的方法来实现这一点。
a.as_ref().map(RefCell::borrow).as_deref()as_ref()用于将Option<RefCell<_>>转换为Option<&RefCell<_>>,以避免使用它。如果您已经有了一个this.map(RefCell::borrow),因为您从hash_map.get()或类似的地方获得了它,那么您可以跳过它,如果它存在的话,可以跳过.borrow()来调用它的值。这将创建一个Option<Ref<'_, _>>.as_deref(),相当于对存在的值调用.deref()。这样做很重要,而不是试图将.borrow()和.deref()合并到一个.map()调用中,因为这样可以使中间的Ref<'_, _>值保持活动状态。
a.as_ref().map(|a| a.borrow().deref())error[E0515]: cannot return reference to temporary value
--> src/main.rs:8:24
|
8 | a.as_ref().map(|a| a.borrow().deref())
| ----------^^^^^^^^
| |
| returns a reference to data owned by the current function
| temporary value created here另外,如果有这样的多个参数,并且希望将它们拆分成变量,那么一定要独立地使用Ref<'_, _>部件,并在使用它的地方使用.as_deref()。同样,这也是保持中间Ref<'_, _>活动所必需的:
let a_ref = a.as_ref().map(RefCell::borrow);
let b_ref = b.as_ref().map(RefCell::borrow);
let c_ref = c.as_ref().map(RefCell::borrow);
f(a_ref.as_deref(), b_ref.as_deref(), c_ref.as_deref());https://stackoverflow.com/questions/71461796
复制相似问题