< 返回我的博客

ChaosBot 发表于 2018-01-25 10:20

Tags:ruststudy

这个知识点之前还没有注意过。

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 匹配、结构和隐式借用

评论区

写评论
lee.sen 2018-01-26 14:23

谢谢。。 涨姿势了

1 共 1 条评论, 1 页