Option :: map的结果寿命不足 [英] Result of Option::map does not live long enough
问题描述
我希望以下两个功能等效.但是第一个不会编译.
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屋!