大白话rust系列08 当变量遮蔽遇上引用,探究变量遮蔽的本质

如果不了解什么是变量遮蔽,可以看这篇文章:大白话rust系列04 变量遮蔽

请问如下代码的打印结果是什么?

rust 复制代码
fn main() {    
    let language = String::from("Rust");
    let language_ref = &language;
    let language = 10;
    println!("language_ref ={},language = {}",language_ref,language);
}

运行结果如下:

rust 复制代码
language_ref =Rust,language = 10

let language = 10; 是新建一个同名变量 (遮蔽旧的),不是修改旧变量的值 。language_ref 指向的是旧的那个 String 的内存 ,那块内存从头到尾没被动过,所以打印出来还是 "Rust"。变量名可以复用,但每个变量各自对应不同的内存区域。

也就是说

rust 复制代码
 let language = String::from("Rust");

和

rust 复制代码
let language = 10;

它们的内存地址不是同一个

把它们的地址打印出来看看吧,代码会稍微多一点点

rust 复制代码
fn main() {
    let language = String::from("Rust");
    let language_ref = &language;

    // 打印第一个 language(String)相关地址
    // 1) String 结构体本身(栈上)的地址
    let addr1_var = &language as *const String as usize;
    // 2) String 底层堆缓冲区("Rust" 实际所在)的地址
    let addr1_heap = language.as_ptr() as usize;
    // 3) language_ref 指向的地址(应等于 1)
    let addr_ref = language_ref as *const String as usize;

    println!("第一次 language(String 变量本身,栈上)地址: 0x{:x}", addr1_var);
    println!("第一次 language 底层堆缓冲区(\"Rust\")地址:   0x{:x}", addr1_heap);
    println!("\nlanguage_ref 指向的地址:                        0x{:x}", addr_ref);

    let language = 10;  // 新变量,遮蔽旧的

    let addr2_var = &language as *const i32 as usize;
    println!("\n第二次 language(i32 变量本身,栈上)地址:      0x{:x}", addr2_var);

    println!("\nlanguage_ref ={},language = {}\n", language_ref, language);
}

运行结果

rust 复制代码
第一次 language(String 变量本身,栈上)地址: 0xde023cfaa8
第一次 language 底层堆缓冲区("Rust")地址:   0x29ca21ea090

language_ref 指向的地址:                        0xde023cfaa8

第二次 language(i32 变量本身,栈上)地址:      0xde023cfb44

language_ref =Rust,language = 10
相关推荐
喵了几个咪2 小时前
GoWind ShortPlay 拆解:不用模型的推荐闭环——埋点回流、三路召回与已看去重
开发语言·后端·微服务·golang·gowind
谙弆悕博士2 小时前
用 C 写了个 Windows 聊天室,踩了几个多线程和控制台的坑
c语言·开发语言·c++·windows·网络编程·聊天室
SimonKing2 小时前
又找到一个纯Java的OCR项目,识别的格式还挺多
java·后端·程序员
Canmag 兴隆磁性2 小时前
回复磁导率 μ_R:永磁体在动态磁路中的关键参数
开发语言·学习·r语言·永磁材料·充磁·磁导率
CRMEB系统商城2 小时前
鲜花零售的预售与积分营销
开发语言·人工智能·科技·小程序·零售
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 喜欢与取消喜欢
java·开发语言·交友
程序猿DD2 小时前
OctaFuse Gateway 2.17.0:新增维护模式、请求日志汇总、DashScope 语音路由拆分
后端
轻舟技术A3 小时前
Pi、rpi、Pi-Bolt 重测:rpi 在启动、内存与读取上全面领先
人工智能·rust
quantdash_cc3 小时前
如何检查滚动收益率计算中的窗口长度不足?——从数学定义到 Pandas 实现
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash