趣味学Rust基础篇(变量与可变性)

这篇文章将用通俗的比喻和清晰的逻辑,带你深入理解 Rust 变量背后的核心思想,让你不仅“会用”,更能“明白为什么”。

Rust 的“盒子哲学”:变量、可变性、常量与隐藏

想象一下,Rust 里的变量就像一个个盒子。你把值(比如数字、文字)装进盒子里,然后给盒子贴上标签(变量名),以后就能通过标签找到盒子里的东西了。但 Rust 对这些盒子的管理非常严格,这正是它安全、高效的核心所在。让我们来看看 Rust 的“盒子管理规则”。

规则一:盒子默认是“上锁”的(不可变性)

在 Rust 世界里,当你创建一个盒子时,它默认是上锁的,这意味着你一旦把东西放进去,就不能再改变了!这听起来有点“死板”?但其实这非常聪明!

为什么上锁是好事?

想象一下,你和朋友合伙开公司,你们约定好“公司注册资本是 100 万”。如果这个数字可以随意修改,那会出大问题!今天改 200 万,明天改 50 万,账就乱了。

在编程中也一样。如果一个值(比如“最大玩家数量”)被标记为不可变,整个程序的其他部分都可以放心地认为它不会变。这避免了“我这里以为是 100,你那里偷偷改成了 200”这种难以追踪的 bug。

试试看:

fn main() {let x = 5; // 创建一个叫 x 的盒子,放进去数字 5,并上锁。println!("x 的值是:{x}");x = 6;     // 试图把 6 放进去?不行!盒子上锁了!println!("x 的值是:{x}");
}

运行这段代码,Rust 编译器会立刻跳出来大喊:“错误!你不能给一个上锁的盒子(不可变变量 x)重新赋值!” 它甚至会贴心地告诉你:“嘿,如果你真的想让它能变,试试加个 mut 吧!”

规则二:想改?请先“解锁”(可变性 mut

如果你确实需要一个能随时修改的盒子,Rust 允许你“解锁”,但必须明确地申请。方法就是用 mut 关键字。

fn main() {let mut x = 5; // 创建一个叫 x 的盒子,放进去 5,但这次是“可解锁”的!println!("x 的值是:{x}");x = 6;         // 现在可以了!把 5 换成 6。println!("x 的值是:{x}");
}

mut 的深层意义:

  1. 安全:强制你思考“这个值真的需要改变吗?” 大多数情况下,值不需要变,上锁更安全。
  2. 沟通mut 就像一个醒目的标签,告诉其他程序员(包括未来的你):“注意!这个 x 的值可能会在代码后面被修改!” 这让代码更容易理解和维护。

核心思想默认不可变,需要可变时才用 mut。这是 Rust 安全性的基石。

规则三:永不改变的“金盒子”(常量 const

有时候,你有一些值是“铁律”,绝对、绝对、绝对不能变,比如“一小时有 3600 秒”。对于这种值,Rust 有更高级的“金盒子”——常量

const SECONDS_IN_HOUR: u32 = 60 * 60;

常量 vs 普通变量:

特性普通变量 (let)常量 (const)
可变性默认不可变,加 mut 可变永远不可变,不能加 mut
声明位置通常在函数内可以在任何地方,包括全局(整个程序都能用)
值来源可以是运行时计算的结果(如用户输入)只能是编译时就能算出来的值(常量表达式)
命名习惯snake_case(小写下划线)SCREAMING_SNAKE_CASE(全大写下划线)

为什么常量只能是编译时的值?

因为常量是在程序启动前就确定的。它不能依赖于运行时才能知道的东西,比如用户输入或网络请求的结果。60 * 60 在编译时就能算出是 3600,所以没问题。

核心思想:常量是程序的“硬编码规则”,安全、高效、作用域广。


规则四:盒子的“变身术”(隐藏 Shadowing

这是 Rust 一个非常酷的特性!想象一下,你有一个叫 spaces 的盒子,里面装着一串空格 " "。现在,你不想知道空格本身,而想知道它有多长(3个字符)。你不想创建一个新名字(比如 spaces_length),怎么办?

Rust 允许你用同一个名字重新声明一个新盒子,这个新盒子会“隐藏”(Shadow)掉旧的盒子。旧盒子依然存在,但你再也“看不见”它了,只能看到新的。

fn main() {let spaces = "   "; // 第一个 spaces 盒子,装着字符串 "   "let spaces = spaces.len(); // 变!用同名新盒子,装着旧盒子的长度 3println!("spaces 的值是:{spaces}"); // 打印出来是 3
}

隐藏 vs mut:关键区别!

  1. 改变类型

    • 隐藏:可以!第一个 spaces字符串,第二个 spaces数字。类型变了!
    • mut不行! 一旦盒子类型定下来(比如 let mut x = 5;i32),就不能再改成其他类型。
    fn main() {let mut spaces = "   "; // spaces 是字符串类型spaces = spaces.len(); //  错误!你不能把一个数字塞进一个声明为字符串的盒子!
    }
    
  2. 安全性

    • 隐藏:每次都是创建一个全新的盒子。旧盒子被隐藏,但不会被意外修改。
    • mut:是同一个盒子,里面的值被直接修改。如果多处代码都 mut 同一个变量,容易出错。
  3. 重置可变性

    • 隐藏:你可以“先 mut 后隐藏为不可变”。比如,先创建一个 mut 盒子进行一系列计算,最后用 let 隐藏它,使其变为不可变,后续代码就安全了。

核心思想:隐藏是“创建新身份”,mut 是“修改旧身份”。隐藏更灵活(能改类型),且在转换完成后能回归不可变的安全状态。

总结:Rust 变量的“四大法宝”

通过这四个规则,Rust 构建了一套强大的内存和数据管理机制:

  1. let (不可变)默认安全。盒子上锁,防止意外修改。
  2. let mut (可变)明确授权。需要修改时才解锁,且明确告知他人。
  3. const (常量)全局铁律。编译时确定,永不改变,作用域广。
  4. let (隐藏)灵活转换。同名换新盒,可改类型,转换后回归安全。

这些规则共同作用,让 Rust 程序在编译时就能捕获大量潜在的错误(比如数据竞争、空指针、类型错误),而无需牺牲运行时性能。这就是 Rust “零成本抽象”和“内存安全”的精髓所在。

现在,你已经理解了 Rust 变量背后的核心哲学。

记住:Rust 不是限制你,而是通过严格的规则,帮你写出更可靠、更高效的代码。 继续探索吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/94522.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/94522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年- H100-Lc208--912.排序数组(快速选择排序)--Java版

1.题目2.思路 快速选择排序的平均时间复杂度是O(nlogn),最坏时间复杂度是O(n^2),最好的时间复杂度是O(nlogn),空间复杂度是O(nlogn)。 排序算法中…

解决 pdf.mjs 因 MIME 类型错误导致的模块加载失败问题

Mozilla PDF.js V4 开始,它官方分发确实只提供了 ESM 模块(.mjs),没有以前的 pdf.js、pdf.worker.js UMD 版本了。 这个问题本质上是 浏览器要求以 application/javascript MIME 类型加载 ES Module,而你引入的 pdf.mj…

STM32八大模式

前言:STM32存在八大模式,分别如下推挽输出,开漏输出,复用推挽输出,复用开漏输出浮空输入,上拉输入,下拉输入,模拟输入STM32标准IO结构图如下:其中如下电路为保护电路&…

OpenCV4.X库功能全解---个人笔记

文章目录前言1.Core核心功能1.1 基本数据类型和结构:1.2 数组操作:1.3 数学函数:1.4 随机数生成:1.5 线性代数运算:1.6 常用数据结构和算法:1.7 XML/YAML文件读写:1.8 错误处理:1.9时…

代码随想录刷题Day44

二叉搜索树的最近公共祖先 这道题,可以沿用二叉树的最近公共祖先的求法进行求解,也就是root判断-左右子树递归求LCA-根据左右子树的LCA结果返回值这一套。 但是,如果要用上搜索二叉树的有序性这个信息的话,就可以直接在递归时候确…

springmvc的数据校验和处理的一个例子

JSR-303是Java 的标准规范,而 Spring MVC 对其提供了完美的支持和集成 1.JSR-303 的身份 JSR-303 是 Java 标准 JSR:Java Specification Request(Java 规范请求) JSR-303:Bean Validation 1.0(Bean 验证规范…

SlowFast使用指南(三)——自建数据集

写在前面 在前两个章节初步使用了SlowFast,使用的都是官方给出的数据集。 附上链接: SlowFast使用指南(一)——demo运行-CSDN博客 SlowFast使用指南(二)——训练ava数据集-CSDN博客 本文尝试了使用自己的数…

Day26 树的层序遍历 哈希表 排序算法 内核链表

day26 树的层序遍历 哈希表 排序算法 内核链表 实现树的层序遍历(广度遍历) 使用队列辅助实现二叉树的层序遍历。算法核心思想是:从根节点开始,依次将每一层的节点入队,出队时访问该节点,并将其左右子节点&…

【系统分析师】高分论文:论快速应用开发方法及应用

【摘要】 我在某县卫生健康委员会公共卫生信息中心工作,是信息中心的负责人。2021年5月,我中心受县痪病预防控制中心委托,为某种痪病疫苗3期临床项日开发受试对象拦截系统。我负责系统架构设计、需求分析以及后期的部分编码工作。通过与庆病预…

4056:【GESP2403八级】接竹竿

/*4056:【GESP2403八级】接竹竿flag 数组 存储每个元素出现的位置,nxt[i]j;存储每个位置 后面第一次出现 与a【i】相等的位置//其中 a【i]a[j] :记录i的下一个位置 ,flag 存储每个值的位置下一次 具有下一次,相当于的链表了&…

企业落地版 AutoGen 多智能体工程(完整示例)

企业生产级参考实现,目标是一套可直接部署的模板工程,包含: FastAPI HTTP API(任务提交、状态查询) Celery 异步任务队列(Redis Broker) PostgreSQL + pgvector(向量存储,RAG) SQLAlchemy + Alembic(ORM 与迁移) AutoGen 多智能体编排(Planner / Coder / Executor…

前端的请求协议对应java的接收

application/json前端发送 JSON 数据,后端用 RequestBody 接收并自动映射为 Java 对象。前端示例(Axios):axios.post("/api/user", { name: "张三", age: 20 }, {headers: { "Content-Type": "…

esp32_hid_device 调试遇到的一些问题

nimble to windows10 22h2esp_hid_device 的keyboardReportMap在win10 22h2 csr4.0 下好像识别不了, Windows(和大多数 BIOS/UEFI)只认 6-byte key array 的 HID Keyboard 描述符。如果不是 6 个字节,Windows HID 驱动就会认为这不…

观察者模式 (Observer Pattern)与几个C++应用例子

1. 模式定义与核心思想 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主题对象的状态发生变化时,它会自动通知所有观察者对象,使它们能够自动更新自己。核心思想: 解耦主题和观察者。主题…

[系统架构设计师]论文(二十三)

[系统架构设计师]论文(二十三) 一.论软件系统架构评估 1.架构所关注的质量属性主要有:性能,可用性,安全性,可修改性 1)性能。性能是指系统的响应能力,即要经过多长时间才能对某个事件…

攻克 Java 分布式难题:并发模型优化与分布式事务处理实战指南

攻克 Java 分布式难题:并发模型优化与分布式事务处理实战指南 开场:从“摇摇欲坠”到“稳如磐石”,你的分布式系统进阶之路 你是否曾经遇到过这样的场景?精心打造的电商应用,在大促开启的瞬间,页面响应变得…

如何在Ubuntu中删除或修改已有的IP地址设置?

在 Ubuntu 中为新增加的网卡设置网络时,需要区分原有网卡和新网卡的配置,确保它们可以独立工作(可在同一网段或不同网段)。以下是具体步骤,假设你需要为新网卡配置静态 IP(以 192.168.1.190/24 为例&#x…

Ansible Playbook 概述与实践案例(下)

#作者:张桐瑞 文章目录四、条件判断的实现五、循环的实现六、Jinja模板应用1、Jinja模板2、handlers组件七、角色 role1、角色介绍2、案例: 部署zabbix-agent四、条件判断的实现 when: 条件 - hosts: appserveruser: roottasks:- name: create userAuser: nameuser…

LeetCode 100 -- Day6

1. 哈希:49、128(1)49 字母异位词分组 -- 字典from collections import defaultdict class Solution(object):def groupAnagrams(self, strs):"""创建字典{sorted_string:原str}"""resultsdefaultd…

多因素认证(MFA/2FA)实战指南:如何保护你的账号

一、MFA/2FA 基础认知 1. 概念辨析与演进 单因素认证(1FA)的局限性:仅依赖 “知识因素”(如密码),据 2024 年 Verizon 数据泄露报告,81% 的账户入侵源于密码泄露 —— 要么是用户使用弱密码&a…