Ref & parameter is special pointer

#![allow(unused)]

/// 总结
/// 1. 引用是一种特殊的指针类型
/// 2. 引用在赋值或传参数时(传参数相当给函数参数赋值),会产生一个新的复本对象,这个新对象的值相同(这个值都是data变量的内存地址)
/// 3. 因为产生副本所以&&的值不相同,&&的值是新复本对象的地址
/// 4. 当在for中时,&&的值相同,原因每次循环生成的新复本对象的地址相同,这里是stack方式的内存,所以二次产生的副本对象地址相同。
/// 5. 引用在相等比较时,是去掉所有的引用,比较的最终的值是否等
/// 6. raw pointer在比较时,是直接比较当前对象的值(也就是指针)是否相待, 不会使用*解引后比较。
fn test_ref_parameters() {
    let data = 1;
    let ref_data = &data;
    let ref2_data = &data;
    let ref3_data = ref_data;
    let d_ref_data = &&data;
    let d2_ref_data = &&data;

    println!("//二次&data指针相等");
    println!("&data: {:p}", &data);
    println!("&data: {:p}", &data);
    println!("//二次for的&data指针相等");
    for _ in 0..2 {
        println!("&data in for: {:p}", &data);
    }
    println!("//二次&&data指针不相等");
    println!("&&data: {:p}", &&data);
    println!("&&data: {:p}", &&data);
    println!("//二次for的&&data指针相等");
    for _ in 0..2 {
        println!("&&data in for: {:p}", &&data);
    }
    println!("//二次赋值给变量的&&data指针不相等");
    println!("&&data: {:p}", d_ref_data);
    println!("&&data: {:p}", d2_ref_data);

    println!("ref_data: {:p}", ref_data);
    println!("ref2_data: {:p}", ref2_data);
    println!("ref3_data: {:p}", ref3_data);
    println!("&ref_data: {:p}", &ref_data);
    println!("&ref2_data: {:p}", &ref2_data);
    println!("&ref3_data: {:p}", &ref3_data);

    assert_eq!(&data, ref_data);
    assert_eq!(&data, ref2_data);
    assert_eq!(&data, ref3_data);
    assert_eq!(&data, &data);

    assert_eq!(&&data, &ref_data);
    assert_eq!(&&data, &ref2_data);
    assert_eq!(&&data, &ref3_data);
    assert_eq!(&&data, &&data);

    fn f(ref_f: &i32, raw: *const i32) {
        println!("ref_f in f : {:p}:{}", ref_f, ref_f);
        println!("&ref_f in f : {:p}:{}", &ref_f, &ref_f);
        let u2 = ref_f as *const i32;
        assert_eq!(u2, raw);
    }

    let raw_data: *const i32 = &data;
    f(&data, raw_data);
}

fn main() {
test_ref_parameters();
}

(Playground)

Output:

//二次&data指针相等
&data: 0x7ffde837e7c4
&data: 0x7ffde837e7c4
//二次for的&data指针相等
&data in for: 0x7ffde837e7c4
&data in for: 0x7ffde837e7c4
//二次&&data指针不相等
&&data: 0x7ffde837e9e8
&&data: 0x7ffde837ea40
//二次for的&&data指针相等
&&data in for: 0x7ffde837eae0
&&data in for: 0x7ffde837eae0
//二次赋值给变量的&&data指针不相等
&&data: 0x7ffde837e7e8
&&data: 0x7ffde837e7f8
ref_data: 0x7ffde837e7c4
ref2_data: 0x7ffde837e7c4
ref3_data: 0x7ffde837e7c4
&ref_data: 0x7ffde837e7c8
&ref2_data: 0x7ffde837e7d0
&ref3_data: 0x7ffde837e7d8
ref_f in f : 0x7ffde837e7c4:1
&ref_f in f : 0x7ffde837e4a8:1

Errors:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 1.67s
     Running `target/debug/playground`

Is there a question?

1 Like

no, but it will be helpful to understand the ref in rust

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.