本篇文章包含的内容

  • 1 变量与常量
  • 2 类型
    • 2.1 标量类型
    • 2.2 复合类型
  • 3 函数
  • 4 控制流
    • 4.1 分支
    • 4.2 循环


1 变量与常量

在Rust中,使用let关键字声明一个变量,变量默认是不可变的。如果要声明可变变量,需要使用mut关键字将其声明为可变变量。

let x = 1;
x = 2;			// 默认不可变,非法
let x = 2;		// shadow,合法let mut y = 1;
y = 2;

声明常量需要使用const关键字,并且在声明时必须指明类型。它甚至可以声明在全局部位,命名需要满足一定的规则:字母全部大写,单词之间用下划线隔开。

const MAX_POINT : u32 = 100_000;

常量一定是不可变的,所以不需要mut关键字声明,但是它与默认不可变的let声明的变量有区别。它的赋值结果只能是常量表达式,不能是函数的返回值或者运行时才可以获得的值。

shadowing(隐藏)是Rust的一个重要特性,它允许新声明的变量的变量名替代旧变量。这在很大程度上提高了程序的可读性。被shadow前后的变量类型可以不同。

let spaces = "    ";			// str
let spaces = spaces.len();		// usize,这里返回 4

2 类型

2.1 标量类型

Rust中有四种标量类型(老四样):

  • 整数:默认i32
  • 浮点:默认f64
  • 布尔:只有两个值,truefalse,占一个字节。
  • 字符:Unicode标量值,占用4个字节,可以表示中日韩字符,emoji表情等。

整数类型具体可由下表表示。其中isizeusize由操作系统决定,如果操作系统是64位,则isize相当于i64usize相当于u64
请添加图片描述
整数的表示与C/C++类似,甚至可以添加下划线以提高可读性。例如10_00000xA00b1100_0011、甚至可以表示为byte类型(u8 only):b'A'。除了byte类型外,其他整数都可以使用类型后缀,例如57u8。如果整数溢出,Rust仅会在debug编译模式下panic(恐慌),而在release版本中程序不会panic。

2.2 复合类型

Rust语言中有两种基础的复合类型,即元组(Tuple)和数组。元组用小括号表示,数组用中括号表示。元组中的每一个元素可以是不同类型,而数组中的所有元素都必须是同一种类型。无论是元组还是数组,都需要显式声明他们的类型。

下面是一个使用元组的例子,可以临时声明一个新的元组,例如(x, y, z)来结构获取旧元组中的每一个成员(Rust会自动推断xyz的类型)。

fn main() {let tup : (i32, i64, u8) = (1, 2, 3);let (x, y, z) = tup;    // destructureprintln!("{}, {}, {}", x, y, z);println!("{}, {}, {}", tup.0, tup.1, tup.2)
}

使用下面的方法定义一个数组,可以显式地制定数组元素的类型,也可以让Rust编译器自动推断所需的数组类型。如果访问的数组索引超出了数组的范围,编译可能不会报错,但是运行时会导致程序panic。

fn main() {let a = [1, 2, 3, 4 , 5];let b: [i32; 5] = [1, 2, 3, 4, 5];let mouths = ["January","February","March","April","May","June","July","August","September","October","November","December"];let arr = [1; 3];   // let arr = [1, 1, 1];println!("{} {}", a[0], b[1]);
}

如果想让数据存放在stack(栈)内存而不是heap(堆)内存上,或者想要保证有固定数量的元素,则可以使用数组。数组是Stack上分配的单个块的内存。数组是定长的,而与之对应可变长度的数组称为Vector(向量)。如果在实际编程中不知道需要使用数组还是Vector,那么一般都需要使用Vector。

3 函数

Rust函数的命名规范采用snake_case规范,即全部小写,单词之间用下划线分开。Rust中的函数定义顺序无需尊循C/C++的习惯,即函数必须先声明再使用,在Rust中,可以将函数的定义放在函数使用之后。函数参数的类型必须指明。

fn main() {another_func(3);
}fn another_func(num: i32) {println!("Another function!");println!("the num is {}", num)
}

Rust是一个基于表达式的语言。任何一个函数体(语句块,由花括号括起)都由一系列语句组成,可选地,可以由一个表达式结束,函数的返回值就是表达式的值(表达式会产生一个计算值)

与表达式对应的概念称为语句,一个语句相当于一个命令,语句没有返回值(它返回一个空的Tuple)。函数的定义也是一个语句,所以它不能当作值赋值给变量(废话),这一点和C/C++有很大不同(笔者认为相当于修复了C/C++的一个bug?)。函数的定义是语句,但是调用函数(宏)是一个表达式。

let x = (let y = 6);		// 非法let y = {let x = 1;x + 2		// 不能加分号
};println!("the value of y is {}", y);	// 3

对于需要返回值的函数,在->符号后声明函数返回值的类型,但是不能为返回值命名。在Rust中,函数的返回值就是函数最后一个表达式的值,如果需要提前返回,则可以使用 return 关键字,并指定一个值

fn main() {let x = add_five(4);println!("{}", x);		// 9
}fn add_five(num: i32) -> i32 {num + 5// return num + 5;
}

4 控制流

4.1 分支

if表达式后需要添加一个条件,条件必须是bool类型(它不能是一个语句,这一点也与C/C++不同),与if相关联的代码称为分支(arm)。当程序中出现多个else if,则建议只用match语句重构代码。

fn main() {let x = 3;if x % 2 == 0 {println!("x can be devived by 2");} else if x % 3 == 0 {println!("x can be devived by 3");} else if x % 4 == 0 {println!("x can be devived by 4")}
}

if是一个表达式,所以它可以放在赋值号的右边。实现类似 ? : ;的效果。需要特别注意的是,ifelse后程序块的返回值的类型必须相同。

let condition = true;let number = if condition { 5 } else { 6 };		// 5

4.2 循环

Rust中有三种循环:loopwhilefor。其使用方法与C/C++和Python比较类似,但是Rust也提供了一些其他的语法糖。

loop表达式中可以使用break语句打断循环,并且break语句后可以添加表达式的值来指定loop表达式的返回值:

fn main() {let mut counter = 0;let result = loop {counter += 1;if counter == 10 {break counter * 2;}};println!("result: {}", result);		// 20
}

while循环使用较为简单,这里不赘述。

遍历集合元素一般使用for。Rust中同样存在迭代器的概念。注意,下面的例子中迭代器返回的是数组a的引用,如果直接写for element in a,则element将会被推断为i32类型,而不是&i32

fn main() {let a = [1, 2, 3, 4, 5];for element in a.iter() {println!("the value is {}", element);}
}

如果需要代码执行确定的次数,可以使用标准库提供的RangeRange可以通过开始数字和结束数字生成一个范围,但不包含结束数字。可以使用rev()方法获得反转的Range

fn main() {for number in (1..4).rev() {println!("{}!", number);}println!("LIFTOFF!");
}

请添加图片描述


  原创笔记,码字不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!博主将持续更新有关嵌入式开发、FPGA方面的学习笔记。


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

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

相关文章

【渲染流水线】[几何阶段]-[图元装配]以UnityURP为例

【从UnityURP开始探索游戏渲染】专栏-直达 前情提要 【渲染流水线】主线索引-从数据到图像以UnityURP为例-CSDN博客 图元装配负责将离散顶点组装成完整几何图元(如点、线、三角形、三角形条带) (对渲染的探索是个持续不断完善的过程&#x…

jvm有哪些垃圾回收器,实际中如何选择?

7.G1收集器一款面向服务端应用的垃圾收集器。 特点如下: 并行与并发:G1能充分利用多CPU、多核环境下的硬 件优势,使用多个CPU来缩短Stop-The-World停顿时间。部分收集器原本需要停顿Java线程来执行GC动作,G1收 集器仍然可以通过并…

多语言与隐形攻击:LLM安全防线为何被频频突破?

你是否曾以为,只要加装了“防火墙”,大型语言模型(LLM)就能高枕无忧?Trendoyl 的实际测试却让我大吃一惊:即便部署了 Meta 的 Llama Guard,攻击者还是能轻松用多语种、字符混淆,甚至…

分布式光伏气象站:为光伏电站的 “气象感知眼”

分布式光伏气象站:为光伏电站的 “气象感知眼”柏峰 【BF-GFQX】在全球能源转型的浪潮中,分布式光伏发电凭借其就近消纳、清洁高效的优势,成为能源结构优化的重要力量。而分布式光伏气象站,作为光伏电站的 “智慧感知眼”&#xf…

TCP与UDP:如何选择最佳传输协议

应用场景选择如果需要可靠传输,首选 TCP如果需要传输的数据包很大,也首选 TCP绝大部分的场景,都可以优先考虑 TCPUDP 相比于 TCP,最大的优点在于传输效率有些情况,既需要可靠性又需要性能,这个时候时候就需…

《Leetcode》-面试题-hot100-栈

题目列表 20. 有效的括号 简单难度 leetcode链接 155. 最小栈 中等难度 leetcode链接 394. 字符串解码 中等难度 leetcode链接 739. 每日温度 中等难度 leetcode链接 84. 柱状图中最大的矩形 困难难度 leetcode链接 题目 (1)有效的括号 题目 给…

GPT-5、Claude-4 同台亮相!OneEval发布全新“大模型+知识库”评测白皮书!

OneEval官网地址:http://OneEval.OpenKG.cnOneEval文章链接:https://arxiv.org/abs/2506.12577要点导读 今年4月,OpenKG发布“大模型知识库”融合能力评估榜单OneEval v1.0。近期,OpenKG在此基础上,组织撰写了OneEv…

【最新版】沃德云商协系统全开源+uniapp小程序

一.介绍沃德云商协是一款基于FastAdmin(thinkphp)Uniapp开发的“多组织”的云服务平台,打造总商会、总协会、总校友会、工商联等多组织无障碍沟通合作平台,让各大分会、各大分校友会、分组织实现轻松管理,线上宣传展示…

Wireshark专家模式定位网络故障:14种TCP异常深度解剖

TCP连接如同精密运转的传送带,每一个异常数据包都是故障的早期信号。作为网络工程师的“外科手术刀”,Wireshark在TCP故障诊断领域的价值无可替代。本文将通过14个真实故障场景,揭示如何利用Wireshark专家系统(Expert System&…

Python Day28 HTML 与 CSS 核心知识点 及例题分析

一、HTML 布局标签(含 H5 语义化标签)传统布局多使用div标签,H5 新增语义化标签增强可读性:核心知识点header:替代div#header,用于页面头部(如标题、导航)。footer:替代d…

MySQL 数据库表操作与查询实战案例

MySQL 数据库表操作与查询实战案例 在数据库学习过程中,熟练掌握表的创建、数据插入及各类查询操作是基础且重要的技能。本文将通过实际案例,详细介绍 MySQL 中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手。 项目一&…

THCV215一种高速视频数据收发器,采用低电压差分信号(LVDS)技术支持高速串行数据传输,支持1080p/60Hz高分辨率传输

THCV215 是一款符合 V-by-One HS 标准的 高速视频数据收发器。THCV215和THCV216被设计为支持主机和显示器之间的视频数据传输。该芯片组可以在20MHz至100MHz的LVDS时钟频率下,仅通过一根差分电缆传输39bit视频数据和3bit同步数据。该芯片组有两个高速数据通道&#…

Linux 系统下 VS Code 降级至 1.85 版本教程:通过历史版本网站解决兼容性问题

一、问题背景 当前使用的 VS Code 版本为 1.102.3,这一版本可能是未来版本、内部测试版或 Insiders 版本,而目前最新的稳定版属于 1.8x 系列。由于版本过新,可能导致与部分插件(如旧版 Remote-SSH)或系统环境不兼容。…

一个基于 PyTorch 的完整模型训练流程

一个基于 PyTorch 的完整模型训练流程 flyfish训练步骤具体操作目的1. 训练前准备设置随机种子、配置超参数(batch size、学习率等)、选择计算设备(CPU/GPU)确保实验可复现;统一控制训练关键参数;利用硬件加…

ffmpeg,ffplay, vlc,rtsp-simple-server,推拉流命令使用方法,及测试(二)

一、常用命令 ffmpeg 推流命令 : ffmpeg -re -i input.mp4 -c copy -f flv rtmp://39.105.129.233/myapp/ffmpeg -re -i input.mp4 -c copy -f flv rtsp://39.105.129.233/myapp/-re 读取流 -i 输入文件 -f # 指定推流formatffplay 拉流命令 : ffplay rtmp://39.105.129.233/m…

使用行为树控制机器人(三) ——通用端口

文章目录一、通用端口功能实现1. 功能实现1.1 头文件定义1.2 源文件实现1.3 main文件实现1.4 tree.xml 实现2. 执行结果使用行为树控制机器人(一) —— 节点使用行为树控制机器人(二) —— 黑板使用行为树控制机器人(三) —— 通用端口有了上述前两节我们已经可以实现节点间的通…

DataDome反爬虫验证技术深度解析:无感、滑块与设备验证全攻略

DataDome反爬虫验证技术深度解析:无感、滑块与设备验证全攻略 随着网络安全威胁的不断演进,企业对数据保护的需求日益增强。DataDome作为业界领先的反爬虫解决方案,以其三层防护机制在众多知名网站中得到广泛应用。本文将深入解析DataDome的…

RabbitMQ 消息转换器详解

RabbitMQ 消息转换器详解 一、为什么需要消息转换器? RabbitMQ 的消息传输协议只识别字节流: 发送对象时,需要序列化成字节数组接收消息时,需要将字节数组反序列化成对象 如果不使用消息转换器: 需要手动序列化和反序列…

内网穿透的应用-告别“现场救火”!用 cpolar远程调试让内网故障排查进入“云时代”

文章目录前言**常见困境与解决方案****实际应用价值**1. Remote JVM Debug2. 系统要求与环境准备2.1 服务器环境2.2 本地开发环境3. 内网服务器准备及开始3.1 安装cpolar配置支持远程ssh登录3.1.1 什么是cpolar?3.1.2 安装cpolar3.1.3 注册及配置cpolar系统服务3.1.…

Cherryusb UAC例程对接STM32内置ADC和PWM播放音乐和录音(下)=>UAC+STM32 ADC+PWM实现录音和播放

1. 程序基本框架整个程序框架, 与之前的一篇文章《Cherryusb UAC例程对接STM32内置ADC和DAC播放音乐和录音(中)>UACSTM32 ADCDAC实现录音和播放》基本一致, 只是这次将DAC替换成了PWM。因此这里不再赘述了。 2. audio_v1_mic_speaker_multichan_template.c的修改说明(略) 参…