这个知识点之前还没有注意过。
fn main() {
let opt = Some("Hello".to_string());
match opt {
Some(_) => println!("We have a string"),
None => println!("We have None"),
}
match opt {
Some(mut s) => {
s.push_str(" world!");
println!("{}", s);
}
None => {}
}
}
上面这段代码,按理说第二个match opt的时候,应该报opt已经被move的错误。但是没有。
如果把第一个match opt匹配分支中的Some(_)改为Some(v),在第二个match opt那里就会报opt已经被move的错误。
然后把Some(_)改为了Some(ref v),照样可以正常运行。
那么是否可以认为, Some(_)中通配符被rust编译器转换为了Some(ref v),此时只是对opt中内容的借用? 继续做实验:
// Some(ref v)
fn main() {
let opt = Some("Hello".to_string());
match opt {
Some(ref v) => drop(opt),
None => println!("We have None"),
}
}
// Some(_)
fn main() {
let opt = Some("Hello".to_string());
match opt {
Some(_) => drop(opt),
None => println!("We have None"),
}
}
Some(ref v)的用法会报错:error[E0505]: cannot move out of opt
because it is borrowed
而Some(_)的用法则不会报错,正常通过。
这说明,编译器对待使用通配符的Some(_)应该是比借用更弱的一种行为,不move也不借用,看起来编译器还比较智能呢。
参考文章:ref 匹配、结构和隐式借用
1
共 1 条评论, 1 页
评论区
写评论谢谢。。 涨姿势了