在您的代码中,不清楚谁是
String
引用于
last: Option<&str>
应该是。您可以引入一个拥有该字符串的额外可变局部变量。但是您将有两个变量:所有者和引用,这看起来是多余的。只做一个
last
业主:
struct MyRes {
str: String,
}
fn main() {
let times = 10;
let mut last: Option<String> = None;
for _i in 0..times {
last = do_something(&last).map(|r| r.str);
}
}
fn do_something(_o: &Option<String>) -> Option<MyRes> {
Some(MyRes {
str: "whatever string".to_string(),
})
}
在
do_something
你可以通过引用来传递整个论点,这似乎更像是你想要的。还要注意,命名自己的结构
Result
是个坏主意,因为
结果
这种普遍的特性深深地嵌入了编译器中吗?(
?
-操作员等)。
后续问题:
Option<&str>
或
Option<String>
?
两个
选项<&str>
和
选项<字符串>
有不同的权衡。一个更适合传递字符串文本,另一个更适合传递所拥有的文本。
弦
实际上,我建议两者都不要使用,而是使函数在类型上为泛型
S
那工具
AsRef<str>
. 以下是各种方法的比较:
fn do_something(o: &Option<String>) {
let _a: Option<&str> = o.as_ref().map(|r| &**r);
let _b: Option<String> = o.clone();
}
fn do_something2(o: &Option<&str>) {
let _a: Option<&str> = o.clone(); // do you need it?
let _b: Option<String> = o.map(|r| r.to_string());
}
fn do_something3<S: AsRef<str>>(o: &Option<S>) {
let _a: Option<&str> = o.as_ref().map(|s| s.as_ref());
let _b: Option<String> = o.as_ref().map(|r| r.as_ref().to_string());
}
fn main() {
let x: Option<String> = None;
let y: Option<&str> = None;
do_something(&x); // nice
do_something(&y.map(|r| r.to_string())); // awkward & expensive
do_something2(&x.as_ref().map(|x| &**x)); // cheap but awkward
do_something2(&y); // nice
do_something3(&x); // nice
do_something3(&y); // nice, in both cases
}
请注意,并非所有上述组合都非常惯用,有些只是为了完整性而添加(例如,请求
asref<str>
然后建立一个拥有的
弦
似乎有点奇怪)。