fn main() { let str = String::from("a"); let a = Some(str); // 获取所有权 let str: String = a.unwrap(); let mut a = Some(str); // let str: Option<&mut String> = a.as_mut(); assert_eq!(str.unwrap(), "a"); // 所有权没有转移 assert_eq!(a.as_mut().unwrap(), "a"); // 注释的代码编译不过,因为str是一个独立的对象,依然遵循所有权规则。 // 不过str中对数据是借阅,而非获取所有权。所以不影响a的所有权。 // assert_eq!(str.as_mut().unwrap(),"a"); assert_eq!(a.as_ref().unwrap_or(&"b".to_string()), "a"); let mut str = Some(Box::new("a".to_string())); // 先做借阅变换,然后对内部数据做解引用变换 let a: Option<&String> = str.as_deref(); let a: Option<&mut String> = str.as_deref_mut(); if let Some(a) = &mut str { // 因为match是借阅方式,所以a也只能是借阅方式,而非拥有。 let a: &mut Box = a; } if let Some(a) = str { //因为match是所有权转移方式,所以str已经被消费掉了,不可以再用 let a: Box = a; } let mut str = Some("a".to_string()); let mut a = None; str.map(|it| { // 注释里的代码有问题,因为map使用的是所有权转移,所以此时str已经无效了 // str = Some(it); a = Some(it); }); str = a; str.take().map(|it| { // take获取str内部的数据,并将str置为None,所以str此时没有未完成的修改动作,所以可以对下面str做重新赋值。 // 通过有无take()的对比。可知,修改有实际分两种,一是对局部数据的改动,一是对整体数据的重新赋值。 str = Some(it) }); }