Rust运算符
【图书介绍】《Rust编程与项目实战》-CSDN博客
《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com)
https://blog.csdn.net/brucexia/category_12779443.html
前面已经学习了变量和常量,本节开始对它们进行操作,这就要用到Rust的操作符(Operator)。操作符通常是由一个或多个特殊的符号组成的(也有非特殊符号的操作符,如as),比如+、−、*、/、%、&、*等。每个操作符都代表一种动作(或操作),这种动作作用于操作数之上。简单来说,就是对操作数执行某种操作,然后返回操作后得到的结果。比如,加法操作3 + 2,这里的+是操作符,加号两边的3和2是操作数,加法符号的作用是对操作数3加上操作数2,得到计算结果5并返回5。
有些语言,很多操作符都是关键字,比如add、equals等。Rust的操作符主要是由符号组成的,比如+、−等。这些符号不在字母表中,但是在所有键盘上都可以找到。这个特点使得Rust程序更简洁,也更国际化。运算符也称操作符。运算符是Rust语言的基础,所以非常重要。
4.1.1 赋值运算符
赋值运算符的功能是将一个值赋给一个变量。比如:
a = 5;
以上代码将整数5赋给变量a。= 运算符左边的部分叫作左值(lvalue,left value),右边的部分叫作右值(rvalue,right value)。左值必须是一个变量,而右值可以是一个常量、一个变量、一个运算的结果,或者是前面几项的任意组合。
有必要强调赋值运算符永远是将右边的值赋给左边,不会反过来。比如:
a = b;
以上代码将变量b的值赋给变量a,不论赋值前a存储的是什么值,这行代码执行后,a的值就和b的值一样了。但要注意,我们只是将b的值赋给a,以后如果b的值改变了,并不会影响a的值。下面来看实例。
【例4.1】 赋值运算符的使用
在命令行下用命令cargo new myrust新建一个Rust项目,项目名是myrust。
打开VS Code,再打开文件夹myrust,然后在VS Code中打开src下的main.rs,输入如下 代码:
fn main() {let mut a:i32;let mut b:i32; //此时a、b的值未知a = 10; // a:10,b未知b = 4; // a:10,b:4a = b; // a:4,b:4b = 7; // a:4,b:7println!("{},{}",a,b);}
以上代码的结果是,a的值为4,b的值为7。最后一行中b的值被改变并不会影响a,虽然在此之前我们声明了a = b;(从右到左规则,right-to-left rule)。
运行结果如下:
4,7
4.1.2 数学运算符
Rust语言支持5种数学运算符,分别为加(+)、减(−)、乘(*)、除(/)、取模(%),括号里的符号就是数学运算符号。加减乘除运算想必大家都很了解,它们和一般的数学运算符没有区别。
唯一你可能不太熟悉的是用百分号(%)表示的取模运算(Module)。取模运算是取两个整数相除的余数。例如,如果我们写a = 11 % 3;,变量a的值将会为2,因为2是11除以3的余数。比如:
fn main() {let mut a:i32;let mut b:i32;let mut c:i32; a = 11 % 3; // 取模运算得a为2b = 4+a; //加法运算得b为6c =(a+b)/2; //除法运算得c为4 println!("{},{},{}",a,b,c);}
输出结果:
2,6,4
4.1.3 组合运算符
Rust以书写简练著称,其一大特色就是这些组合运算符(+=、−=、*=、/=及其他),这些运算符使得只用一个基本运算符就可以改写变量的值:
value += increase; 等同于 value = value + increase;
比如:
- a −= 5; 等同于 a = a − 5;。
- a /= b; 等同于 a = a / b;。
- price *= units + 1; 等同于price = price * (units + 1);。
其他运算符以此类推。下面来看一个组合运算符的例子,代码如下:
fn main() {let mut a:i32;let mut b:i32;let mut c:i32; a = 11 % 3; // a:2b = 4+a; // b:6c =(a+b)/2; //c:3 a+=c; b*=a;c/=2; println!("{},{},{}",a,b,c);}
结果输出:
6,6,4
值得庆幸的是,Rust 语言不支持自增运算符(++)和自减运算符(--),因此本节绝对不会出现类似于a+++++i这样让人血压升高的语句。其实,编程语言由于是给人用的,一定要考虑到人的局限性(就是面对复杂事物容易出错),所以编程语言一定要简单明了,Rust去掉了++和--,相对于C语言而言,绝对是个进步,可以从源头上尽可能防止人类出错。
4.1.4 关系运算符
我们用关系运算符来比较两个表达式,关系运算的结果是一个布尔值,即它的值只能是true或false。例如,我们想通过比较两个表达式来看它们是否相等,或一个值是否比另一个值大。表4-1所示为Rust的关系运算符。
示例代码如下:
fn main() {let mut a:bool;let mut b:bool;let mut c:bool;a=(7!=5);b = (100<=99);c=(6==6);println!("{},{},{}",a,b,c);}
运行结果:true,false,true。
除使用数字常量外,我们也可以使用任何有效表达式,包括变量。比如下列代码:
fn main() {let mut a:i32;let mut b:i32;let mut c:i32;a=2;b=3;c=6;println!("{},{},{}",(a == 5),(a*b >= c),(b+4 > a*c));}
输出结果:false,true,false。(a*b >= c)返回true是因为它实际是(2*3 >= 6),(b+4 > a*c)返回false因为它实际是(3+4 > 2*6)。
值得注意的是,运算符=(单个等号)不同于运算符==(两个等号),前者是赋值运算符(将等号右边的表达式值赋给左边的变量);后者(==)是一个判断等于的关系运算符,用来判断运算符两边的表达式是否相等。
4.1.5 逻辑运算符
运算符!等同于boolean运算NOT(取非),它只有一个操作数(Operand),写在它的右边。它做的唯一工作就是取该操作数的反面值,也就是说如果操作数值为真(true),那么运算后值变为假(false),如果操作数值为假(false),则运算结果为真(true)。它就好像是取与操作数相反的值。例如:
- !(5 == 5)返回false,因为它右边的表达式(5 == 5)为真(true)。
- !(6 <= 4)返回true,因为(6 <= 4)为假(false)。
- !true返回假(false)。
- !false返回真(true)。
大家如果不信,可以用下列代码直接输出看看结果:
println!("{},{},{},{}",!(5 == 5),!(6 <= 4),!true,!false);
逻辑运算符&&和||用来计算两个表达式而获得一个结果值。它们分别对应逻辑运算中的与运算(AND)和或运算(OR)。它们的运算结果取决于两个操作数的关系,如表4-2所示。
例如:
- ( (5 == 5) && (3 > 6) )返回false ( true && false )。
- ( (5 == 5) || (3 > 6))返回true ( true || false )。
大家如果不信,可以用下列代码直接输出看看结果:
println!("{},{}",( (5 == 5) && (3 > 6) ) ,( (5 == 5) || (3 > 6)));
4.1.6 位运算符
位运算符以比特位改写变量存储的数值,也就是改写变量值的二进制表示。Rust的位运算符如表4-3所示。
下面的范例演示上面提到的所有位运算符。
fn main() {let a:i32 = 2; // 二进制表示为 0 0 0 0 0 0 1 0let b:i32 = 3; // 二进制表示为 0 0 0 0 0 0 1 1let mut result:i32;result = a & b;println!("(a & b) => {} ",result);result = a | b;println!("(a | b) => {} ",result) ;result = a ^ b;println!("(a ^ b) => {} ",result);result = !b;println!("(!b) => {} ",result);result = a << b;println!("(a << b) => {}",result);result = a >> b;println!("(a >> b) => {}",result);}
输出结果如下:
(a & b) => 2(a | b) => 3(a ^ b) => 1(!b) => -4(a << b) => 16(a >> b) => 0
4.1.7 变量类型转换运算符
变量类型转换运算符可以将一种类型的数据转换为另一种类型的数据。在Rust中,可以使用关键字as进行类型转换,as 运算符有点像C中的强制类型转换,区别在于,它只能用于原始类型(i32、i64、f32、f64、u8、u32、char等类型),并且它是安全的。注意,不同的数值类型是不能进行隐式转换的。比如:
let b: i64 = iNum; //iNum是一个i32类型的变量
会出现编译错误,提示无法进行类型转换。这时可以使用as 进行转换,比如:
fn main() {let mut iNum:i32; let mut b:i64; iNum=100;b = iNum as i64;print!("{}",b);}
输出结果:100。
为什么as是安全的?尝试以下代码:
b = iNum as char;
编译器报错:
error[E0604]: only `u8` can be cast as `char`, not `i32`
可见在不相关的类型之间,Rust 会拒绝转换,这样避免了运行时错误。
4.1.8 运算符的优先级
当多个操作数组成复杂的表达式时,我们可能会疑惑哪个运算先被计算,哪个后被计算。例如以下表达式:
a = 5 + 7 % 2
我们可以怀疑它实际上表示:a = 5 + (7 % 2) 结果为6,还是 a = (5 + 7) % 2 结果为0?
正确答案为第一个,结果为6。每一个运算符都有一个固定的优先级,不仅是数学运算符(我们可能在学习数学的时候已经很了解它们的优先顺序了),所有在Rust中出现的运算符都有优先级。从最高级到最低级,运算符的优先级按表4-4排列。
以下是简单的示例:
fn main() {//二元计算操作println!("1 + 2 = {}", 1u32 + 2);println!("1 - 2 = {}", 1i32 - 2);//逻辑操作println!("true AND false is {}", true && false);println!("true OR false is {}", true || false);println!("NOT true is {}", !true);//位运算操作println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101);println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101);println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101);println!("1 << 5 is {}", 1u32 << 5);println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2);}
运行结果如下:
1 + 2 = 31 - 2 = -1true AND false is falsetrue OR false is trueNOT true is false0011 AND 0101 is 00010011 OR 0101 is 01110011 XOR 0101 is 01101 << 5 is 320x80 >> 2 is 0x20
所有这些运算符的优先级顺序可以通过使用一对圆括号“()”来控制,而且更易读懂,示例如下:
a = 5 + 7 % 2;
根据我们想要实现的计算不同,可以写成:
a = 5 + (7 % 2);
效果和a = 5 + 7 % 2;一样,因为%的优先级比+高,所以加不加括号没什么区别。如果要先计算5+7,则可以这样:
a = (5 + 7) % 2;
此时最终计算结果就不同了。所以如果想写一个复杂的表达式而不敢肯定各个运算的执行顺序,那么就加上括号。这样可以使代码更易读懂。
相关文章:

Rust运算符
【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com) https://blog.csdn.net/brucexia/category_12779443.html 前面已经学习了变量和常量,本节开始对它们进行操作,…...

Oracle rman 没有0级时1级备份和0级大小一样,可以用来做恢复 resetlogs后也可以
文档说了 full backup 不能 用于后续的level 1,没说level 1没有level 0 是不是level 1就是level 0? 1级备份变0级的原因 及 Enabling Change Tracking生效没有-CSDN博客 这个文档说明1级备份时没有找到0级就是0级备份,可以用来完整恢复的。…...

idea中配置Translation插件完成翻译功能
文章目录 idea下载插件配置有道云阿里云百度翻译开放平台 idea下载插件 idea中安装Translation插件 使用方法:右下角选择翻译引擎,鼠标选中想翻译的部分,右键翻译即可 之前一直用的微软的翻译,不需要配置,但是最近微软…...
如何看待:低代码开发平台的兴起无需经验?
在当今快速发展的技术时代,软件开发的需求日益增长,而专业开发人员的数量却远远跟不上需求的步伐。为了解决这一矛盾,低代码开发平台应运而生,它通过提供可视化的开发环境和拖拽式的编程方式,使得没有编程经验的用户也…...

OpenCV-轮廓检测
文章目录 一、简介1. 意义2.具体步骤 二、代码实现三、总结 一、简介 1. 意义 在OpenCV中,轮廓检测是图像处理中一个非常重要的环节,它允许我们识别图像中的形状。这个过程通常涉及几个步骤:读取图像、转换为灰度图、应用阈值处理ÿ…...

vue页面使用自定义字体
一、准备好字体文件 一般字体问价格式为 .tff,可以去包图网等等网站去下载,好看的太多了!!! 下载下来就是单个的 .tff文件,下载下来后可以进行重命名,但是不要改变他的后缀名,我把他…...
C++——list常见函数的使用和模拟实现(2)
在list的上一篇博客里实现了list基本的初始化、插入数据、删除数据的基本功能,这些功能的实现方式只是在原先链表的实现里加入了模版而已,但是list作为一个容器,它还有一个基础的东西——迭代器。list的迭代器和之前实现的string和vector很大…...
C 标准库 - `<float.h>`
C 标准库 - <float.h> 概述 <float.h> 是 C 标准库中的一个头文件,它定义了与浮点数类型相关的宏。这些宏提供了关于浮点数的属性信息,如精度、最小和最大值、以及舍入误差等。这个头文件对于需要精确控制浮点数行为的程序非常有用&#x…...

【机器人工具箱Robotics Toolbox开发笔记(二)】Matlab中机器人工具箱的下载与安装
Matlab机器人工具箱(Robotics Toolbox)可从Peter Corke教授提供的网站上免费下载。网址为:http://www.petercorke.com/Robotics_Toolbox.html。 图1 网站所提供的机器人工具箱版本 在Downloading the Toolbox栏目中单击here按钮进入下载页面,然后在该页面中填写国家、组织…...

ROS2 Nav2 - Smac 规划器
系列文章目录 前言 SmacPlanner 是 Nav2 Planner 服务器的插件。它目前包括 3 个不同的插件: SmacPlannerHybrid:高度优化的完全可重新配置的 Hybrid-A* 实现,支持 Dubin 和 Reeds-Shepp 模型(足式、阿克曼和汽车模型)…...

LabVIEW环境中等待FPGA模块初始化完成
这个程序使用的是LabVIEW环境中的FPGA模块和I/O模块初始化功能,主要实现等待FAM(Field-Programmable Gate Array Module,FPGA模块)的初始化完成,并处理初始化过程中的错误。让我们逐步分析各部分的功能: 1.…...

手机TF卡格式化后数据恢复:方法、挑战与预防措施
在现代生活中,手机已经成为我们不可或缺的一部分,而TF卡(即MicroSD卡)作为手机存储的扩展,更是承载了我们大量的重要数据。然而,不慎的格式化操作往往导致数据丢失,给用户带来不…...

ceph对象存储使用的一些思考
导言 我在某司做对象存储约4年时间,作为研发人员,接触过大量的市场项目,对国内市场上对对象存储的使用有一些了解和思考。本文主要是对本人经历的过往对象存储项目中发现的一些问题进行总结。 背景如下: 基于ceph版本进行开发并进…...

单词排序C++实现
代码如下: #include<iostream> #include<string> #include<fstream> #include<map> #include<iomanip> #include<algorithm> #include<vector>int read_file(std::map<std::string,int> &map_words) {std::st…...

828华为云征文 | Flexus X 实例服务器网络性能深度评测
引言 随着互联网应用的快速发展,网络带宽和性能对云服务器的表现至关重要。在不同的云服务平台上,即便配置相同的带宽,实际的网络表现也可能有所差异。因此,了解并测试服务器的网络性能变得尤为重要。本文将以华为云X实例服务器为…...

STL —heap算法源码刨析 make_heap、push_heap、pop_heap、sort_heap操作分析
STL —heap算法源码刨析 heap算法概述push_heap 插入元素pop_heap 取出根节点元素sort_heap 按极值存放元素make_heap 将一段现有数据构造成heap程序测试 heap算法概述 heap的内部是一个完全二叉树,将极值存放在根节点。这个里的极值可分为最大值、最小值。根据极值…...

走进低代码表单开发(一):可视化表单数据源设计
在前文,我们已对勤研低代码平台的报表功能做了详细介绍。接下来,让我们深入探究低代码开发中最为常用的表单设计功能。一个完整的应用是由众多表单组合而成的,所以高效的表单设计在开发过程中起着至关重要的作用。让我们一同了解勤研低代码开…...

简单好用的OCR API
现如今,越来越多的科技产品可以帮助我们改善和提高相应的工作效率。OCR技术的出现,提高了人们的工作效率,其应用领域及其广泛。就拿应用了OCR技术的翔云文档识别服务来说,只需上传文档图片便可自动识别并返回文档中相应的内容。翔…...
c++的拷贝构造函数和赋值函数
拷贝构造函数和赋值函数 什么是拷贝构造 是一种特殊构造函数,如果没有显式的实现,编译器就会自动生成。 class 类名 { public:// 拷贝构造类名(const 类名& that){} }; 什么时候会调用拷贝构造 当使用一个类对象给另一个新的类对象初始化时&…...

什么自动猫砂盆才适合旅游党?4个选购技巧统统告诉你!
有没有能让我们防夹3天不在家都不用担心猫咪铲屎问题的方法?当然有了!自动猫砂盆就是最好的选择,要知道,有个好用合适的自动猫砂盆在家的话,根本不用担心生虫发臭的问题出现,因为自动猫砂盆能及时感应到猫咪…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...