首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Option<RefCell<T>>转换为Option<&T>

将Option<RefCell<T>>转换为Option<&T>
EN

Stack Overflow用户
提问于 2022-03-13 23:59:07
回答 1查看 183关注 0票数 2

我们知道,很容易将RefCell<T>类型的值转换为&T类型的值,以便作为函数中的参数使用:

代码语言:javascript
复制
fn main() {
    let a: RefCell<i32> = RefCell::new(0);
    my_func(a.borrow().deref());
}

fn my_func(i: &i32) {}

在我的场景中,RefCell被存储在HashMap中,因此它们被包装在Option中。我还希望传递给它们的函数有选项的概念,但我只想传递不可变的引用,而不是整个RefCell。我们可以这样做:

代码语言:javascript
复制
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对每个参数嵌套,并以指数方式增长。因此,有办法这样做是有帮助的:

代码语言:javascript
复制
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的问题,但是它的寿命不够长。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-14 00:46:07

您可以使用Option上的方法来实现这一点。

代码语言:javascript
复制
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<'_, _>值保持活动状态。

代码语言:javascript
复制
a.as_ref().map(|a| a.borrow().deref())
代码语言:javascript
复制
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<'_, _>活动所必需的:

代码语言:javascript
复制
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());
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71461796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档