Rust中的一些细枝末节

Rust中的&解引用。

 let v3 = Some('a');
    match v3.as_ref() {
        Some(&c) => {
            let addr = std::ptr::addr_of!(c);
            println!("addr of c: {:?}", addr);
            println!("addr of v3: {:?}", ptr::addr_of!(v3));
        }
        None => {}
    }

 let v5: Option<i32> = Some(10);
    match v5.as_ref() {
        Some(c) => {
            let addr = std::ptr::addr_of!(c);
            println!("addr of c: {:?}", addr);
            println!("addr of v4: {:?}", ptr::addr_of!(v5));
        }
        _ => {}
    }

  let v4 = Some(10);
    match v4.as_mut() {
        Some(&mut c) => { 
			c=20;//编译失败,报错:无法对C的值赋值两次
		}
        _ => {}
    }

代码如上,v3和v5都能编译通过,但打印的值却不同。
v3中 解引用出来的变量c和v3的地址不是同一个,v5中c的值和v5的地址是同一个。在v3中Some(&c),做了两件事,一:解引用,使用Some(&c)匹配v3.as_ref()。二:将v3中的值赋值到变量c中,因为char类型实现了Copy trait,因此可以直接赋值,这也就导致了c和v3的地址不是同一个(因为发生了拷贝)。而v5中的c就代表了&i32,只是将i32的引用进行了赋值,因此他们指向的地址还是同一个。

v4中编译失败,理解了v3中赋值的问题不难理解。Some(&mut c)实现了解引用和赋值,但赋值后的c和v4中的值已经不是一个地址了,因此在编译层面直接就不通过(不符合可变性规则)。重新分析v4的逻辑不难发现,无非就是要修改v4中的值,此时就可以直接Some(c), 此时的c的类型为v4值的可变引用(&mut i32),指向了v4中的值的地址,因此可以直接修改。

posted @ 2026-03-31 10:33  伊森-w  阅读(10)  评论(0)    收藏  举报