Rust 选项的生命周期::map';s论点
我将一个字符串放入Rust 选项的生命周期::map';s论点,rust,Rust,我将一个字符串放入选项并尝试在其上映射,例如修剪字符串: 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); } 编译
选项
并尝试在其上映射,例如修剪字符串:
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);
}
编译器显示一个生存期错误
错误[E0597]:`z`活得不够长
-->src/main.rs:5:27
|
5 |设x=s|u opt.map(| z | z.trim());
|^-`z`在还借来的时候掉在这里了
| |
|借来的价值活得不够长
...
9 | }
|-借来的价值需要一直存在到这里
这一点很清楚,因为z
仅在闭包中定义,并且参数是按值传递的
既然原始变量s
适用于整个块,编译器难道不能找出z
实际上是s
我唯一能做到这一点的方法是将添加到_string
(请参见注释行),然后创建一个新的string对象
我发现的另一个解决方案是使s_opt
成为选项的一种类型(请参见第二个代码块),但由于函数不能返回这种类型,因此这实际上不是一个选项
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);
}
fn我的地图选项&r str,
{
匹配*o{
无=>无,
一些(参考x)=>一些(f(x)),
}
}
fn main(){
let s=“我想要修剪”。to_string();
让s_opt=Some(s);
设x=my_map(&s_opt,| x | x.trim());
println!(“{:?}”,x);
}
map
函数使用迭代值,因此在调用给定闭包后,这些值不再存在。不能返回对它们的引用
最好的解决方案是直接在字符串上进行就地修剪。遗憾的是,目前标准库中没有
您的第二个解决方案也可以通过一个小的改变。使用&str
代替&String
:
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
使用原始值生成输出值。这是最灵活、最高效的实现,因为您可以转换选项。一旦您有了选项
,您就可以使用它而不会失去原始选项的所有权
:
谢谢PEPP的回复。实际上,我在使用std::io时遇到了问题。返回的类型是IoResult
(例如read\u line)。因此,不能使用第二种解决方案。因此,我必须使用作为_slice().trim().to _string()
解决方案或使用try!宏并将其包装在一个附加函数中。我说得对吗?
fn main() {
let s = Some(" i want to be trimmed ".to_string());
let x = s.as_ref().map(|z| z.trim());
println!("{:?}", x);
}