以下是我可以使用 Rust 1.23.0 编译的有效文件:
fn main() {
let r = String::from("a");
let a = Some(&r);
let b = match a {
Some(name) => name,
None => "",
};
println!("{}", b);
}
虽然下面的代码
fn main() {
let r = String::from("a");
let a = Some(&r);
let b = a.unwrap_or("");
println!("{}", b);
}
失败并出现错误:
error[E0308]: mismatched types
--> src/main.rs:4:25
|
4 | let b = a.unwrap_or("");
| ^^ expected struct `std::string::String`, found str
|
= note: expected type `&std::string::String`
found type `&'static str`
据我所知,编译器在这里确定类型时的推理如下:
在
match
它确定b
是 a的情况下&str
,因为None => ""
是 a&str
并且Some(name) => name
是 a&String
所以它可以变成 a&str
。如果 to 的参数
unwrap_or
是 a&str
,而不是键入b
a ,它会看到(即)中保存的类型和 to 的参数类型&str
之间存在差异。a
&String
unwrap_or
这两种使类型推导以这种方式工作的情况有什么区别?
是否被unwrap_or
实现为接受与选项包装的类型完全相同的类型,而不是只接受它放置在 match 中的通用值?
此外,在这种情况下,有什么方法可以完成unwrap_or
工作,而不必String
在外部范围内声明 a 或更改选项包装的类型?
我在其他地方得到的一个让它们工作的答案是:
let b = a.map(|s| s.as_ref()).unwrap_or("")
与 相同的效果match
,比match
关于类型发生的事情更短,更明确。