Option::map 参数的生命周期 [英] Lifetime of Option::map's argument
问题描述
我将一个字符串放入一个 Option
并尝试映射它,例如修剪字符串:
I placee a string into an Option
and try to map over it, e.g. to trim the string:
fn main() {
let s = " i want to be trimmed ".to_string();
let s_opt = Some(s);
let x = s_opt.map(|z| z.trim());
// let x = s_opt.map(|z| z.trim().to_string());
println!("'{:?}'", x);
}
编译器显示生命周期错误
The compiler shows a lifetime error
error[E0597]: `z` does not live long enough
--> src/main.rs:5:27
|
5 | let x = s_opt.map(|z| z.trim());
| ^ - `z` dropped here while still borrowed
| |
| borrowed value does not live long enough
...
9 | }
| - borrowed value needs to live until here
这很清楚,因为 z
仅在闭包中定义并且参数是按值传递的.
This is clear, since z
is only defined in the closure and the argument is passed by value.
由于原始变量 s
存在于整个块中,编译器是否应该能够确定 z
实际上是 s
?
Since the original variable s
lives for the entire block, shouldn't the compiler be able to figure out that z
is actually s
?
我可以让它工作的唯一方法是添加 to_string
(请参阅注释行),但随后我正在创建一个新的字符串对象.
The only way I can get this to work is by adding to_string
(see the commented line), but then I am creating a new string object.
我发现的另一个解决方案是使 s_opt
成为一种 Option<&String>
(请参阅第二个代码块),但由于函数无法返回此这种类型这不是一个真正的选择.
Another solution I found is to make s_opt
a type of Option<&String>
(see the second code block), but since functions can't return this kind of type this is not really an option.
fn main() {
let s = " i want to be trimmed ".to_string();
let s_opt = Some(&s);
let x = s_opt.map(|z| z.trim());
println!("'{:?}'", x);
}
是否有什么我忽略的地方,或者如果 map
的默认实现与此类似,会不会更好?
Is there something I've overlooked or wouldn't it be better if the default implementation of map
would be similar to this?
fn my_map<'r, F>(o: &'r Option<String>, f: F) -> Option<&'r str>
where
F: Fn(&'r String) -> &'r str,
{
match *o {
None => None,
Some(ref x) => Some(f(x)),
}
}
fn main() {
let s = " i want to be trimmed ".to_string();
let s_opt = Some(s);
let x = my_map(&s_opt, |x| x.trim());
println!("'{:?}'", x);
}
推荐答案
map
函数使用迭代值,因此在调用给定闭包后它们不再存在.您不能返回对它们的引用.
The map
function consumes iterated values so they do not exist after the call to the given closure anymore. You cannot return references to them.
最好的解决方案是直接对 String
进行就地修剪.遗憾的是,目前标准库中没有.
The best solution would be in-place trim on String
directly. Sadly there is none in the standard library currently.
您的第二个解决方案也可以稍作改动.而不是 &String
你取一个 &str
:
Your second solution is also possible with a small change. Instead of &String
you take a &str
:
fn main() {
let s = "text".to_string();
let s_opt = Some(s.as_str());
let x = s_opt.map(|z| z.trim());
println!("{:?}", x);
}
这篇关于Option::map 参数的生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!