函数、表达式与控制流:Rust 的核心语法构建块
myzbx 2025-07-17 22:54 3 浏览
在上一篇中我们了解了变量与类型,本篇将深入函数、表达式与控制流的使用,让你的代码更具逻辑性。
一、函数定义与调用
函数是组织和复用代码的基本单元。在 Rust 中,使用 fn 关键字定义函数:
/// 计算两个数字的和
///
/// # 参数
/// * `a` - 第一个数字
/// * `b` - 第二个数字
///
/// # 返回值
/// 返回两个数字的和
fn add(a: i32, b: i32) -> i32 {
a + b // 最后一行表达式为函数返回值
}
fn main() {
let sum = add(2, 3);
println!("2 + 3 = {}", sum);
}
- fn:定义函数
- add:函数名
- (a: i32, b: i32):参数列表,格式为 名称: 类型
- -> i32:返回类型
- 函数体最后一个表达式不加分号,作为返回值
函数的所有权规则
fn main() {
let s = String::from("hello");
takes_ownership(s); // s 的所有权被移动到函数中
// println!("{}", s); // 错误:s 已经被移动
let x = 5;
makes_copy(x); // x 是 i32,实现了 Copy trait
println!("{}", x); // 正确:x 仍然可用
}
fn takes_ownership(some_string: String) {
println!("{}", some_string);
} // some_string 在这里离开作用域并被丢弃
fn makes_copy(some_integer: i32) {
println!("{}", some_integer);
} // some_integer 在这里离开作用域
函数返回值与所有权
fn main() {
let s1 = gives_ownership(); // 函数返回值所有权移给 s1
let s2 = String::from("hello"); // s2 进入作用域
let s3 = takes_and_gives_back(s2); // s2 被移动到函数中,返回值所有权移给 s3
} // s3 离开作用域并被丢弃,s2 已被移动,s1 离开作用域并被丢弃
fn gives_ownership() -> String {
let some_string = String::from("hello");
some_string // 返回 some_string 并移出给调用者
}
fn takes_and_gives_back(a_string: String) -> String {
a_string // 返回 a_string 并移出给调用者
}
二、表达式(Expression)与语句(Statement)
o 表达式 会计算并返回值,如函数调用或算术运算:
let x = 5 + 6; // 5 + 6 是表达式,返回 11
let y = {
let z = 3;
z + 2 // 块表达式,返回 5
};
o 语句 执行动作但不返回值,以分号结尾:
let x = 5; // 这是语句
表达式的类型
1. 字面量表达式
let x = 42; // 整数字面量
let y = 3.14; // 浮点数字面量
let z = "hello"; // 字符串字面量
2. 运算符表达式
let sum = 1 + 2; // 算术运算符
let eq = 1 == 2; // 比较运算符
let and = true && false; // 逻辑运算符
3. 块表达式
let result = {
let x = 10;
let y = 20;
x + y // 块表达式的返回值
};
4. if 表达式
// a b 变量需自定义
let max = if a > b { a } else { b };
表达式优先级
Rust 中常见的运算符优先级(从高到低):
1. 一元运算符:!, -, *, &, &mut
2. 算术运算符:*, /, %, +, -
3. 位移运算符:<<, >>
4. 位运算符:&, |, ^
5. 比较运算符:==, !=, <, >, <=, >=
6. 逻辑运算符:&&, ||
let result = 2 + 3 * 4; // 等价于 2 + (3 * 4)
三、if条件表达式
if 在 Rust 中是表达式,可直接赋值:
let number = 7;
let kind = if number % 2 == 0 {
"偶数"
} else {
"奇数"
};
println!("{} 是 {}", number, kind);
注意:所有分支须返回相同类型。
四、loop无限循环
loop 用于创建无限循环,可用 break 退出,并可返回值:
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 4 {
break counter * 2;
}
};
println!("结果是 {}", result); // 结果是 8
循环标签
当有嵌套循环时,可以使用标签来指定 break 或 continue 的目标:
'outer: loop {
println!("进入外层循环");
'inner: loop {
println!("进入内层循环");
break 'outer; // 直接跳出外层循环
}
println!("这行永远不会执行");
}
break 和 continue 的更多用法
// break 可以返回值
// some_condition 变量需自定义
let result = loop {
if some_condition {
break 42; // 返回 42
}
};
// continue 跳过当前迭代
for i in 0..5 {
if i == 2 {
continue; // 跳过 2
}
println!("{}", i); // 打印 0,1,3,4
}
五、while条件循环
当条件满足时重复执行:
let mut n = 3;
while n != 0 {
println!("{}!", n);
n -= 1;
}
println!("开始执行!");
六、for范围循环
遍历范围或集合:
for i in 0..5 {
println!("i = {}", i); // 0,1,2,3,4
}
// 倒序
for i in (1..=3).rev() {
println!("{}", i); // 3,2,1
}
七、练习题(动手最重要)
1. 定义函数 is_even(n: i32) -> bool,在 main 中测试。
2. 使用 if 表达式实现成绩评级:90+ A,>=60 B,否则 C。
3. 用 loop 计算 1 到 5 的累加和,并返回结果。
4. 用 while 实现倒计时,从 5 到 1。
5. 用 for 循环打印数组 ["rust", "by", "example"] 中的每个元素。
八、小结
本篇我们学习了:
- 函数的定义与调用
- 表达式与语句的区别
- 核心控制流关键字:if, loop, while, for
九、下一篇预告
下一篇我们将进入 所有权、借用与生命周期,探索 Rust 安全性的核心机制,敬请期待!
欢迎关注、收藏和转发,也可以留言你最想了解的内容,有任何问题可以留言或私信,我会尽力解答!
喜欢编程、区块链、Web3
可加好友
相关推荐
- 资深架构师亲授,从堆栈到GC,一篇文章打通任督二脉!
-
“又双叒OOM了?”“服务半夜崩了,日志全是`java.lang.OutOfMemoryError`...”“GC停顿太长,用户投诉卡顿!”如果你也常被这些问题折磨,根本症结往往在于:你对Java...
- Java JAR 启动内存参数配置指南:从基础设置到性能优化
-
在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键。本文将系统讲解如何通过命令行参数、环境变量等方式指定内存配置,并结合实际场景提供优化建议。一、核心内存...
- 浏览器存储"四大家族":谁才是你的数据管家?
-
当你关闭浏览器再重新打开,登录状态为何还在?购物车商品为何不会消失?这些"记忆"背后,藏着浏览器存储的"四大家族"——Cookie、localStorage、sessi...
- SOP与SIP深度解析(sop与soic)
-
SOP(标准作业程序)与SIP(标准检验程序)是确保产品质量和生产效率的两大支柱,分别聚焦于生产执行和质量验证。一、核心区别:目标与作用域维度SOP(标准作业程序)SIP(标准检验程序)定位指导“如何...
- Java 技术岗面试全景备战!从基础到架构的系统性通关攻略分享
-
Java技术岗的面试往往是一项多维度的能力检验。本文将会从核心知识点、项目经验到面试策略,为你梳理一份系统性的备战攻略!需要的同学可以私信小编【学习】一、技术基础:面试的“硬性指标”1.最重要的还是...
- C++11 新特性(c++11新特性 pdf)
-
一、核心语言革新移动语义与右值引用通过&&标识临时对象(右值),实现资源转移而非复制。例如移动构造函数将原对象资源指针转移后置空,避免深拷贝,极大优化容器操作性能。12类型推导auto:自动推导变量类...
- 2026年前每个开发者都应该学习的技能
-
优秀开发者和伟大开发者之间的差距正在快速扩大。随着AI工具的爆炸式增长、自动化工作流程和日益复杂的技术栈,开发者不能再仅仅"知道如何编码"了。在2026年及以后,您的优势不仅仅是编写代...
- 看一看,Python这四种作用域你都知道吗?
-
点赞、收藏、加关注,下次找我不迷路一、啥是作用域?先打个比方比如说,你在自己的卧室(相当于一个小空间)里放了一本书,这本书在卧室里随便你怎么看,这就是这本书在卧室这个"作用域"内...
- 抛弃立即执行函数 (IIFE),拥抱现代 JavaScript 块级作用域
-
IIFE(ImmediatelyInvokedFunctionExpression)曾是JavaScript开发中的重要工具,但随着ES6+的块级作用域特性,我们现在有了更优雅的替代...
- 2025 年是时候重新认识 Symbol 的八大特性了?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是Symbol原始类型在J...
- 函数、表达式与控制流:Rust 的核心语法构建块
-
在上一篇中我们了解了变量与类型,本篇将深入函数、表达式与控制流的使用,让你的代码更具逻辑性。一、函数定义与调用函数是组织和复用代码的基本单元。在Rust中,使用fn关键字定义函数:///计算...
- 所有权、借用与生命周期:理解 Rust 的核心机制
-
上一篇我们学习了函数、表达式和控制流,这一篇将正式进入Rust最核心、最独特的语言机制:所有权系统。一、为什么需要所有权机制?在C/C++中,内存管理依赖开发者手动操作,容易出现野指针、重复...
- Rust 语言的借用规则:构筑安全内存管理体系的核心保障机制
-
前言在系统级编程范畴内,内存安全始终是一项极具挑战性的关键议题。Rust语言凭借其独树一帜的「借用规则」(BorrowingRules),于编译阶段便有效规避了诸如空指针、野指针以及数据竞争等一系...
- 函数编写指南:参数、返回值与作用域实战详解
-
你是否在编写函数时遇到过参数传递混乱、返回值逻辑不清晰,或者变量作用域导致的奇怪bug?别担心,这篇文章将用最通俗的语言和实战案例,带你彻底搞懂函数的核心三要素:参数、返回值与作用域。一、参数:灵活...
- 服务器频繁报错?5 步教你快速排查修复!运维必看!
-
服务器突然报错、网站打不开、数据库连不上……这些问题是不是让你头大?别慌!今天教你一套「望闻问切」的排查法,90%的服务器故障都能轻松解决!一、定位错误类型:先看日志再动手1.日志是关键系统日志...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)