当前位置: 首页 > news >正文

Rust基础-part3-函数

Rust基础[part3]_函数、流程控制

函数

组成和定义

fn add(i: i32, j: i32) -> i32 {i + j
}
  • 声明函数的关键字 fn
  • 函数名add()
  • 参数i和j和参数类型 i32
  • 返回值类型`i32``
  • 函数题i+j

函数返回

返回形态

i+jreturn i+j;

可以有两种形态

  • return + 分号
  • 无return + 无分号
无返回值的情况

就返回 ()

fn add(i: i32, j: i32) -> () {}
永不返回值的情况:

!表示函数永不返回,例如panic!宏会导致程序崩溃,函数不会返回。

fn add_one(i: i32, j: i32) -> ! {panic!("weeee");
}

死循环也不会返回

fn infinite_loop() -> ! {loop {// 永远不会返回}
}

流程控制

if语法

   // if_else();let number = 3;if number < 5 {println!("Condition was true");} else {println!("Condition was false");}// else iflet number = 3;if number % 4 == 0{println!("Condition was true");} else if number % 3 == 0 {println!("Condition was true for number % 3");} else if number % 2 == 0 {println!("Condition was true for number % 2");} else {println!("Condition was false");}

let 语句中使用if,需要注意分号结尾。

 let condition = true;let number = if condition { 5 } else { 6 };println!("The value of number is: {}", number);

loop循环

//loop 循环loop {println!("This is an infinite loop");}
break、 continue

使用break 关键字来告诉程序停止循环,使用continue关键字来告诉程序继续循环。

let语句中也可以使用loop返回, 需要注意分号结尾。

 // let语句中使用looplet result = loop {count += 1;if count == 10 {println!("Breaking the loop at count: {}", count);break count * 2; // 返回值}};
多层loop

break退出内层循环,可以使用命名loop的方法来退出指定的循环。标签的语法是使用单引号(')后跟一个标识符

 // 多层循环可以使用标签来控制跳出特定的循环层级// 标签可以帮助我们在多层嵌套循环中跳出特定的循环层级// 标签的语法是使用单引号(')后跟一个标识符let mut i = 0;'outerloop: loop {loop {i += 1;println!("Inner loop iteration with i: {}", i);if i == 2 {println!("Breaking out of the inner loop at i: {}", i);break; // 跳出内层循环}if i == 3 {println!("Breaking out of the outer loop at i: {}", i);break 'outerloop; // 跳出外层循环}}}

while 条件循环

fn while_example() {let mut count: i32 = 0;while count < 5 {count += 1;println!("Current count: {}", count);}
}

在rust中如果是条件判断的循环,使用while是比较便捷的,如果需要遍历集合的话,可以使用for

for遍历集合

fn for_example() {let numbers = [1, 2, 3, 4, 5];for i in numbers {println!("Current number: {}", i)}// 直接遍历数值,逆序使用rev()for i in (1..=4).rev() {println!("Current number in range: {}", i);}
}
所有权转移与借用:

是Rust中的循环访问规则

1. 未实现Copy trait的类型:所有权会转移(Move语义)

Vec这类集合类型没有实现Copy trait,当直接用它们进行循环遍历(for v in vec)时,循环会获取vec的所有权(即“所有权转移”)。

  • 循环结束后,vec的所有权已被消耗,无法再被访问(编译器会报错)。
let mut vec = vec![1, 2, 3, 4, 5];
// 直接遍历vec:所有权转移给循环变量v
for v in vec {println!("Current value: {}", v); // 此时v是vec中元素的所有权持有者
}// ❌ 错误:vec的所有权已转移,无法再使用
println!("Vector after loop: {:?}", vec); 
2. 解决办法:用“借用”避免所有权转移

若想在循环后继续使用vec,需通过引用(&) 进行“借用”,而非直接转移所有权。根据是否需要修改元素,分为两种借用方式:

(1)不可变借用(&vec):仅读取,不修改

&vec进行遍历,循环获取的是vec不可变引用,所有权仍归原变量所有。

  • 循环中只能读取元素,不能修改。
let vec = vec![1, 2, 3, 4, 5];
// 不可变借用:&vec表示“临时借用vec的读取权”
for v in &vec {println!("Current value: {}", v); // v是&i32类型(不可变引用)
}// ✅ 合法:vec所有权未转移,可继续使用
println!("Vector after loop: {:?}", vec); 
(2)可变借用(&mut vec):需要修改元素

若要在循环中修改元素,需用&mut vec进行可变借用,此时循环变量v&mut i32(可变引用)。

  • 修改元素时需用*v解引用(获取引用指向的实际值)。
let mut vec = vec![1, 2, 3, 4, 5];
// 可变借用:&mut vec表示“临时借用vec的修改权”
for v in &mut vec {if *v == 3 {*v += 10; // ✅ 解引用后修改:3 → 13}println!("Current value: {}", v); // v是&mut i32,打印时自动解引用
}// ✅ 合法:所有权未转移,修改后的值已保留
println!("Vector after loop: {:?}", vec); // 输出 [1, 2, 13, 4, 5]
3. 实现Copy trait的类型:所有权不转移(Copy语义)

像整数、布尔值等基本数据类型,以及由它们组成的数组([i32; n]),都实现了Copy trait

  • 循环遍历这类类型时,会自动复制元素(而非转移所有权),原变量的所有权仍保留,循环后可正常使用。
let arr = [1, 2, 3, 4, 5]; // 数组元素是i32(实现了Copy)
// 遍历arr:会复制每个元素给v,而非转移所有权
for v in arr {println!("Current value: {}", v); // v是复制的i32值
}// ✅ 合法:arr的所有权未转移,可继续使用
println!("Array after loop: {:?}", arr); // 输出 [1, 2, 3, 4, 5]
核心区别总结
类型特征循环方式所有权状态循环后能否使用原变量
未实现Copy(如Vecfor v in vec所有权转移给v不能(已被消耗)
未实现Copy(如Vecfor v in &vec仅借出不可变引用能(所有权仍保留)
未实现Copy(如Vecfor v in &mut vec仅借出可变引用能(所有权仍保留)
实现Copy(如[i32; n]for v in arr元素被复制,所有权不转移能(原变量未被修改)
http://www.dtcms.com/a/274899.html

相关文章:

  • 如何在 PyCharm 批量调整代码缩进?PyCharm 调整代码格式化和代码缩进的快捷键有哪些?
  • Pandas:常见的转换函数(rename,set_index,reset_index)
  • 麦迪逊悬架cad【14张】+三维图+设计说明书
  • VLLM部署DeepSeek-LLM-7B-Chat 模型
  • 云网络产品
  • 简单记录一下Debug的折磨历程
  • 多项式环及Rq的含义
  • Solaris10 创建用户初始化家目录
  • 注意力机制十问
  • softmax回归的从零开始实现
  • Java 抽象类详解:从基础到实战,掌握面向对象设计的核心基石
  • 渗透测试之木马后门实验
  • 拥抱AI----AI时代下的SSM框架
  • 项目捷报 | 冠捷科技泰国工厂THA MES项目成功验收!TPV国际化布局再添里程碑!
  • 【中文核心期刊推荐】中国农业科技导报
  • php的原生类
  • 7.12 卷积 | 最小生成树 prim
  • 转转APP逆向
  • WIFI协议全解析06:Beacon帧、Probe帧你必须懂,搞WiFi通信绕不开它们
  • RAG知识库检索查询优化技术
  • 【实时Linux实战系列】 KVM-RT 与 Jailhouse 虚拟化
  • C++ 面向对象 - 默认值与常量成员
  • sensor_msgs中常用的传感器数据格式以及c++操作
  • 数字孪生技术引领UI前端设计新风尚:智能穿戴设备的界面优化
  • MongoDB(一)
  • 用Python和OpenCV从零搭建一个完整的双目视觉系统(六 最终篇)
  • 【9】PostgreSQL 之 vacuum 死元组清理
  • bash脚本-z检查参数是否为空
  • 雨污管网智慧监测系统网络建设方案:基于SD-WAN混合架构的最佳实践
  • 计算机组成原理:以ADD指令为例讲解微指令执行流程