我将一个字符串放入一个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());
// let x = s_opt.map(|z| z.trim().to_string());
println!("'{:?}'", x);
}
编译器显示了生命周期错误
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
仅在闭包中定义,且参数通过值传递。
由于原始变量s
在整个块中都存在,编译器不应该能够弄清楚z
实际上是s
吗?
我唯一能让它工作的方法是添加to_string
(请参见注释行),但那样我就会创建一个新的字符串对象。
我找到的另一种解决方案是将s_opt
作为Option<&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());
println!("'{:?}'", x);
}
我有什么遗漏的吗?或者默认实现的map
是否类似于此更好?
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);
}
IoResult<String>
(例如read_line)。因此第二种解决方案无法使用。因此,我必须使用as_slice().trim().to_string()
解决方案或者使用try!宏并将其包装在额外的函数中。我是对的吗? - wiep