我希望能够在借来的上下文中打开一个可选项。例如,println!
某个值:
struct Optional {
v: Option<String>,
v2: Option<String>,
}
fn main() {
let mut optionals = vec![];
optionals.push(Optional { v: Some("foo".to_string()), v2: Some("bar".to_string())});
optionals.push(Optional { v: None, v2: None });
for optional in &optionals {
println!("v:{} v2:{}", optional.v.unwrap_or("none".to_string()), optional.v2.unwrap_or("none".to_string()));
}
}
我的理解是,这是不可能的,因为借用了optional
而unwrap_or
消费了它的输入,这是因为它被借用而被禁止。我尝试将ref
带到结构值但又失败了,如何在不消耗optionals
的情况下实现我想要的目标。
答案 0 :(得分:3)
使用Option::as_ref
。在您的示例中,您还必须处理需要将&String
的类型与默认值匹配的事实。
let v = optional.v.as_ref().map(|s| s as &str).unwrap_or("none");
let v2 = optional.v2.as_ref().map(|s| s as &str).unwrap_or("none");
println!("v:{} v2:{}", v, v2);
作为ker points out,您还可以映射AsRef::as_ref
:
let v = optional.v.as_ref().map(AsRef::as_ref).unwrap_or("none");
let v2 = optional.v2.as_ref().map(AsRef::as_ref).unwrap_or("none");
println!("v:{} v2:{}", v, v2);
作为qthree points out,.map().unwrap()
的版本较短。像Rust Clippy这样的工具可以帮助您找到这些工具,当您没有一大批优秀的程序员查看您的代码时; - ):
let v = optional.v.as_ref().map_or("none", |s| s as &str);
let v2 = optional.v2.as_ref().map_or("none", AsRef::as_ref);
println!("v:{} v2:{}", v, v2);
这是在借用的上下文中打印可选项的最惯用的方法吗?
这是值得商榷的。例如,如果打印的值为"none"
,那么读者无法知道它实际上是Some("none")
还是None
。这种区别对您的代码的操作有影响吗?
如果我要将数据打印到终端以供程序员使用,我更有可能只使用Debug
格式化程序进行打印:
println!("v:{:?} v2:{:?}", optional.v, optional.v2);
虽然我真的只为Debug
派生Optional
并打印整件事:
#[derive(Debug)]
struct Optional { ... }
for optional in &optionals {
println!("{:?}", optional);
}
如果真的是供用户使用,我可能会有不同的短语:
match optional.v {
Some(ref s) => println!("The value is: {}", s),
None => println!("The value is not set"),
};