从RefCelL<Option>>获得参考.在锈 [英] Obtain the a reference from a RefCelL<Option<T>> in Rust

查看:48
本文介绍了从RefCelL<Option>>获得参考.在锈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难从 RefCell> 中获取引用.

struct Consumer2{尾部:RefCell,}实施<T>消费者2 T{fn read(&self) ->Ref<Option<&T>>{Ref::map(self.tail.borrow(), |v1| 匹配 v1 {无 =>&无,一些(v2)=>&Some(v2),})}}

编译器指出了一个生命周期问题.

有关此错误的更多信息,请尝试 `rustc --explain E0495`.错误[E0495]:由于需求冲突,无法推断出适当的模式生命周期-->src/lib.rs:28:18|28 |一些(v2)=>&Some(v2),|^^|注意:首先,生命周期不能超过 26:38 在主体上定义的匿名生命周期 #1 ...-->src/lib.rs:26:38|26 |Ref::map(self.tail.borrow(), |v1| 匹配 v1 {|______________________________________^27 ||无 =>&无,28 ||一些(v2)=>&Some(v2),29 ||})||_____^注意:...以便参考不会超过借来的内容-->src/lib.rs:28:18|28 |一些(v2)=>&Some(v2),|^^注意:但是,生命周期必须对 25:13 在方法主体上定义的匿名生命周期有效...-->src/lib.rs:25:13|25 |fn read(&self) ->Ref<Option<&T>>{|^^^^^注意:...这样表达式是可赋值的-->src/lib.rs:26:9|26 |/Ref::map(self.tail.borrow(), |v1| 匹配 v1 {27 ||无 =>&无,28 ||一些(v2)=>&Some(v2),29 ||})||_____^= 注意:预期的`Ref<'_,Option<&T>>`找到`Ref<'_,Option<&T>>

我不确定我是否理解问题本身.

解决方案

当你添加生命周期注解时,你会得到这样的结果:

impl<T>消费者2 T{fn read(&'s self) ->Ref<Option<>>>{Ref::map(self.tail.borrow(), |v1: &'a Option| match v1 {无 =>&无,Some(v2: &'a T) =>&Some(v2),})}}

由于生命周期省略规则,返回的推断生命周期是 self 的生命周期.来自 Rust Book:><块引用>

第二条规则是,如果只有一个输入生命周期参数,则该生命周期将分配给所有输出生命周期参数: fn foo<'a>(x: &'a i32) ->&'a i32.

<块引用>

第三条规则是如果有多个输入生命周期参数,但其中一个是 &self 或 &mut self 因为这是一种方法,self 的生命周期被分配给所有输出生命周期参数.

因此 rust 期望返回值具有 self 的生命周期.

但是在传递给 Ref::map 的闭包中,它获得了另一个生命周期 'a,因为第一个省略规则:

<块引用>

(...) 每个作为引用的参数都有自己的生命周期参数

Rust 不能保证借用的对象会比闭包更长寿,因此它不能保证 's'a 的生命周期相等或 'a> 比返回类型推断的生存期所需的 寿命更长.

正如@Siscia 指出的那样,这不能编译

简而言之:尝试为您的参数提供明确的生命周期:

impl<T>消费者2 T{fn read(&'s self) ->Ref<Option<>>>{Ref::map(self.tail.borrow(), |v1: &'s Option| match v1 {无 =>&无,一些(v2)=>&Some(v2),})}}

但是您可能会遇到其他问题,因为从闭包返回引用几乎从来都不是一个好主意.

但这有效:

impl<T>消费者2 T{fn read(&self) ->Ref<Option<T>{Ref::map(self.tail.borrow(), |v1| 匹配 v1 {无 =>&无,一些 =>&一些,})}}

I am having a hard time getting a reference out of a RefCell<Option<T>>.

struct Consumer2<T> {
    tail: RefCell<Option<T>>,
}

impl<T> Consumer2<T> {
    fn read(&self) -> Ref<Option<&T>> {
        Ref::map(self.tail.borrow(), |v1| match v1 {
            None => &None,
            Some(v2) => &Some(v2),
        })
    }
}

The compiler point out to a lifetime issue.

For more information about this error, try `rustc --explain E0495`.
error[E0495]: cannot infer an appropriate lifetime for pattern due to conflicting requirements
  --> src/lib.rs:28:18
   |
28 |             Some(v2) => &Some(v2),
   |                  ^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 26:38...
  --> src/lib.rs:26:38
   |
26 |           Ref::map(self.tail.borrow(), |v1| match v1 {
   |  ______________________________________^
27 | |             None => &None,
28 | |             Some(v2) => &Some(v2),
29 | |         })
   | |_________^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:28:18
   |
28 |             Some(v2) => &Some(v2),
   |                  ^^
note: but, the lifetime must be valid for the anonymous lifetime defined on the method body at 25:13...
  --> src/lib.rs:25:13
   |
25 |     fn read(&self) -> Ref<Option<&T>> {
   |             ^^^^^
note: ...so that the expression is assignable
  --> src/lib.rs:26:9
   |
26 | /         Ref::map(self.tail.borrow(), |v1| match v1 {
27 | |             None => &None,
28 | |             Some(v2) => &Some(v2),
29 | |         })
   | |__________^
   = note: expected `Ref<'_, Option<&T>>`
              found `Ref<'_, Option<&T>>

I am not sure if I understand the issue itself.

解决方案

When you add lifetime annotations, then you get something like that:

impl<T> Consumer2<T> {
    fn read(&'s self) -> Ref<Option<&'s T>> {
        Ref::map(self.tail.borrow(), |v1: &'a Option<T>| match v1 {
            None => &None,
            Some(v2: &'a T) => &Some(v2),
        })
    }
}

The inferred lifetime for return is the lifetime of the self because of the lifetime elision rules. From Rust Book:

The second rule is if there is exactly one input lifetime parameter, that lifetime is assigned to all output lifetime parameters: fn foo<'a>(x: &'a i32) -> &'a i32.

The third rule is if there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all output lifetime parameters.

So rust expects that return value will have lifetime of self.

But in closure passed to Ref::map it gets another lifetime 'a, because of the first elision rule:

(...) each parameter that is a reference gets its own lifetime parameter

Rust cannot guarantee that borrowed object will outlive the closure, so it cannot guarantee that 's and 'a lifetimes are equal or 'a outlives the 's which is required by return type inferred lifetime.

EDIT: As @Siscia pointed out this doesn't compile

In short: try to give explicit lifetime to your parameters:

impl<T> Consumer2<T> {
    fn read(&'s self) -> Ref<Option<&'s T>> {
        Ref::map(self.tail.borrow(), |v1: &'s Option<T>| match v1 {
            None => &None,
            Some(v2) => &Some(v2),
        })
    }
}

But you probably will have other problems, because returning references from closure is nearly never a good idea.

But this works:

impl<T> Consumer2<T> {
    fn read(&self) -> Ref<Option<T>> {
        Ref::map(self.tail.borrow(), |v1| match v1 {
            None => &None,
            some => &some,
        })
    }
}

这篇关于从RefCelL&lt;Option&gt;&gt;获得参考.在锈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆