惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V2EX - 技术
V2EX - 技术
Security Archives - TechRepublic
Security Archives - TechRepublic
Cisco Talos Blog
Cisco Talos Blog
T
Tor Project blog
博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
宝玉的分享
宝玉的分享
小众软件
小众软件
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Spread Privacy
Spread Privacy
I
InfoQ
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
M
MIT News - Artificial intelligence
爱范儿
爱范儿
The Cloudflare Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
Tenable Blog
S
Securelist
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
Webroot Blog
Webroot Blog
The Hacker News
The Hacker News
O
OpenAI News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes
PCI Perspectives
PCI Perspectives
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threat Research - Cisco Blogs
L
LINUX DO - 热门话题
I
Intezer
Scott Helme
Scott Helme
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cybersecurity and Infrastructure Security Agency CISA
Google Online Security Blog
Google Online Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Security Affairs
AI
AI
AWS News Blog
AWS News Blog
Security Latest
Security Latest

博客园 - PKICA

编译配置解答 git实用命令 rust底层设计理念值得注意的几个地方总结 rust可变引用作为函数参数的机理详解 Rust内存重解释transmute C与Rust类型映射 Rust FFI 安全抽象范式 rust延迟初始化原语 rust重借用机制与原理 汇编语言语法详解 gdb汇编调试 gdb-pwndbg的安装与使用指南 gdb调试插件gef C语言thread_local linux系统readelf命令使用指南 gcore转储进程内存 gdb查看命令 RGB与YUV颜色编码的区别 Rust原子类型 C++ STL求两个集合交集差集 gdb调试集锦 ubuntu24.0.4使用root用户登录 ubuntu24.0.4输入密码后跳回登录界面 AI内存压缩技术TurboQuant及存疑 ubuntu切换到指定内核版本 在没有顶级科技大佬直接背书的情况下deepseek为啥能够异军突起? HuggingFace和deepseek的关系 当前主流AI大模型 Rust写时克隆Cow系列2
rust参数传递模型
PKICA · 2026-05-26 · via 博客园 - PKICA

🛠 核心概念:程序设计语言中的参数传递模型

参数传递模型决定了数据如何在“上层调用者(Caller)”与“被调用函数(Callee)”之间流转。它不仅关乎代码的编写方式,更直接决定了程序的内存开销、数据安全性以及外部变量是否会被意外篡改。

我们将以底层的 C 语言 与现代的 Rust 语言 为例,从内存、权限和应用场景三个维度进行系统化拆解。


1. 值传递 (Pass by Value) 与 本地副本修饰

💡 核心原理

当一个变量以“值”的形式传进函数时,系统会在当前函数的栈帧(Stack Frame)中创建该数据的一个全新拷贝(副本)。函数内部所有的操作,都是在这个独立的“沙盒副本”中进行的。


🇨 C 语言实现:常规值传递

void modify_value(int val) {
    val = 20; // 修改的是局部栈帧中的副本
}

int main() {
    int num = 10;
    modify_value(num);
    // 结果:num 依然是 10
}
  • 底层行为:在进入 modify_value 时,内存中复制出了一个新的 val(值为 10)。
  • 外部影响:完全不可见。函数返回后,副本随栈帧销毁。

🦀 Rust 语言实现:mut val: i32

在 Rust 中,值传递的行为取决于数据是否实现了 Copy 特征(Trait)。对于基础类型(如 i32, u16),它的底层同样是复制一个新副本,但 Rust 引入了更严苛的局部可变性控制。

fn modify_value(mut val: i32) {
    val = 20; // 允许修改!因为有 mut 修饰
}

fn main() {
    let num = 10;
    modify_value(num);
    // 结果:num 依然是 10
}
  • mut 的真实含义:这里的 mut 属于局部权限修饰符。它不是在改变上层调用者的变量权限,而是函数在向编译器申请:“在这个函数内部,我允许自己修改这个新复制出来的变量副本”。
  • 外部影响:完全不可见。上层调用者的 num 甚至不需要是 mut 的。

2. 引用/指针传递 (Pass by Pointer / Reference)

💡 核心原理

函数不再复制原始数据,而是接收原始数据在内存中的地址(指针)。借由这个地址,函数内部的操作可以穿透当前的栈帧,直接对上层调用者内存空间里的真实数据进行改写。


🇨 C 语言实现:指针传递

void modify_by_pointer(int *ptr) {
    *ptr = 20; // 显式解引用,直接修改地址对应的内存
}

int main() {
    int num = 10;
    modify_by_pointer(&num); // 传入 num 的内存地址
    // 结果:num 变成了 20
}
  • 底层行为:传递的是一个 8 字节(64位系统)的内存指针。
  • 主要职责:
    1. 作为输出参数(Output Parameter):当函数需要返回多个处理结果,或者返回值已被错误码(Error Code)占用时,用来将数据带回给上层。
    2. 减少内存开销:当传递大型结构体(Struct)时,避免产生高昂的复制代价。

🦀 Rust 语言实现:可变借用 ptr: &mut i32

Rust 在底层硬件行为上与 C 语言的指针完全一致,但在语义安全层面引入了极其严格的“借用检查器(Borrow Checker)”规则。

fn modify_by_reference(ptr: &mut i32) {
    *ptr = 20; // 显式解引用(在很多上下文里 Rust 也会自动隐式解引用)
}

fn main() {
    let mut num = 10; // 外部变量必须也是可变的
    modify_by_reference(&mut num); // 显式传入可变引用
    // 结果:num 变成了 20
}
  • 安全防线(独占锁锁机制):Rust 强制规定,在同一时间、同一作用域内,一个数据只能存在一个活跃的可变引用(&mut)。这意味着当这个函数在操作 num 时,任何其他线程或代码都无法读取或修改 num,从根本上在编译期杜绝了“数据竞争(Data Race)”和“并发死锁”。
  • 外部影响:必定可见。

📊 终极对比矩阵

特性C: int val / Rust: val: i32Rust: mut val: i32C: int *ptr / Rust: ptr: &mut i32
内存本质 复制一个新副本 复制一个新副本 传递原始数据的内存地址
内部修改权限 ❌ 无法在函数内修改该参数 允许在函数内修改副本 允许直接修改外部原始数据
外部可见性 ❌ 外部变量毫无变化 ❌ 外部变量毫无变化 外部变量同步被修改
典型应用场景 仅需要读取入参进行计算。 临时将入参作为函数内部的局部变量、计数器使用。 需要将函数执行的结果通过参数“带回”给上层调用者。

参考资料: