百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

函数、表达式与控制流: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

循环标签

当有嵌套循环时,可以使用标签来指定 breakcontinue 的目标:

'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内存参数是保障应用稳定性和性能的关键。本文将系统讲解如何通过命令行参数、环境变量等方式指定内存配置,并结合实际场景提供优化建议。一、核心内存...

浏览器存储&quot;四大家族&quot;:谁才是你的数据管家?

当你关闭浏览器再重新打开,登录状态为何还在?购物车商品为何不会消失?这些"记忆"背后,藏着浏览器存储的"四大家族"——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.日志是关键系统日志...