【发布时间】:2018-08-30 00:20:40
【问题描述】:
以下是我可以用 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是&str,因为None => ""是&str而Some(name) => name是&String,所以它可以变成@987654331 @.如果
unwrap_or的参数是&str,而不是将b键入为&str,它会发现a中保存的类型(即@ 987654337@) 和参数的类型为unwrap_or。
这两种情况有什么区别使类型推导以这种方式工作?
unwrap_or 是否实现了接受与选项包装的类型完全相同的类型,而不是只接受它放在匹配项中的通用值?
此外,有什么方法可以让unwrap_or 在这种情况下工作,而无需在外部范围内声明String 或更改选项包装的类型?
我在其他地方得到的一个让它们起作用的答案是:
let b = a.map(|s| s.as_ref()).unwrap_or("")
与match 的效果相同,略短,比match 更明确地说明类型发生了什么。
【问题讨论】:
标签: generics rust option rust-result