Option :: map的结果寿命不足 [英] Result of Option::map does not live long enough

查看:78
本文介绍了Option :: map的结果寿命不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望以下两个功能等效.但是第一个不会编译.

I expected the two functions below to be equivalent. However the first one does not compile.

pub fn does_not_work<I: IntoIterator>(values: I)
where
    I::Item: AsRef<str>,
{
    if let Some(value) = values.into_iter().nth(0).map(|item| item.as_ref()) {
        if value == "first" {
            println!("This should print");
        }
    }
}

pub fn does_work<I: IntoIterator>(values: I)
where
    I::Item: AsRef<str>,
{
    if let Some(value) = values.into_iter().nth(0) {
        if value.as_ref() == "first" {
            println!("This should print");
        }
    }
}

fn main() {
    does_work(&["first"]);
}

编译错误为:

error[E0597]: `item` does not live long enough
 --> src/main.rs:5:63
  |
5 |     if let Some(value) = values.into_iter().nth(0).map(|item| item.as_ref()) {
  |                                                               ^^^^        - `item` dropped here while still borrowed
  |                                                               |
  |                                                               borrowed value does not live long enough
...
9 |     }
  |     - borrowed value needs to live until here

对代码进行了更改,以使其不比其来自的实际上下文更冗长,并更清楚地说明了这一点.为了阐明为什么要使用第一种方法,我在实际代码中多次使用了value,并且我不想让每一个都跟一个.as_ref().

The code is altered so as to be less verbose than the actual context it comes from and to more clearly illustrate the point. To clarify why I want to use the first approach, I use value many more times in my actual code and I don't want to have every single one of them followed by a .as_ref().

有没有办法使这种工作有效,或者Option::map在这种情况下不是一个好的选择吗?是否有另一种简洁的方法可以解决此问题?

Is there a way to make this work or is Option::map not a good choice for this situation? Is there another concise way to solve this problem?

推荐答案

创建新的迭代器时,旧值不再可用.但是您需要存在旧值才能返回Some(value).在您的情况下,您要将&[&'static str]传递给函数,因此可以保证将其保留足够长的时间,但是根据类型,您也可以传递&[String].

When you create a new iterator, old values are not available anymore. But you need the old value to exist in order to return Some(value). In your case, you're passing a &[&'static str] to the function, so it's guaranteed to stay around long enough, but according to the types you could just as well pass &[String].

在这种情况下,原始的String可能会被释放,而您将留下一个悬空的指针.通过不调用.as_ref(),可以保证原始值将在Some(value)中可用.

In that case, the original String could be freed and you'd be left with a dangling pointer. By not calling .as_ref(), you guarantee that the original value will be available in the Some(value).

如果您只想跳过多个.as_ref()通话,则可以执行以下操作:

If you just want to skip multiple .as_ref() calls you can instead do:

pub fn does_work<I: IntoIterator>(values: I)
where
    I::Item: AsRef<str>,
{
    if let Some(value) = values.into_iter().next() {
        let s = value.as_ref();
        if s == "first" {
            println!("This should print");
        }
    }
}

这篇关于Option :: map的结果寿命不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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