rust变量与常量

news2024/10/7 10:23:12

变量绑定

在rust里有个核心原则,那就是所有权。在其它语言中,我们可以把一个值赋值给变量。但是在rust里,是把值绑定到变量上。任何内存对象都是有主人的,而且一般情况下完全属于它的主人,绑定就是把这块内存绑定给一个变量,让这个变量成为它的主人。

不可变变量

在rust里,默认情况下变量是不可变的。一旦变量被声明为不可变,那么一旦为它绑定值,就不能再修改。变量的声明方式如下所示:

let variable_name:type = value

let是rust声明变量的关键字。下面是一个例子:

fn main() {
    let num = 123;          
    println!("{}", num);    // {}是占位符,类似与C/C++中的%d, %s等
}

示例中声明了一个不可变变量num,绑定的值是123。如果尝试对num进行修改,会报错。例如:

fn main() {
    let num = 123;
    println!("{}", num);
    num = 456;              // 错误,不能对不可变变量进行二次赋值。
    println!("{}", num);
}

使用cargo check来进行语法检查,报错如下所示:
在这里插入图片描述

类型声明

如果你仔细观察你的vscode编辑器,就会发现如下所示的细节。
在这里插入图片描述
i32是rust的基本数据类型,这里是rust编译器帮我们进行了类型推断,将num设置为i32类型。大多数情况下,rust编译器都可以帮助我们进行类型的推断,但是偶尔也无法推断,这时候我们就要手动声明变量的数据类型了。例如:在这里插入图片描述
rust编译器帮助我们推断的类型是i32,但是你使用cargo check检查的时候,就会发现有语法错误。rust编译器非常智能的提示你,i32的范围是-2147483648到2147483647,而111111111111不在这个范围内,并且提示你可以使用i64类型替代i32类型。让我们将i32改为i64,再执行cargo check。
在这里插入图片描述
可以看到,成功通过了语法检查。在现在的版本(rust1.65),可以通过下面的方式来获取数据类型的名称。

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

例如:

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

fn main() {
    let s = "Hello";
    let i = 42;
    print_type_of(&s); // &str
    print_type_of(&i); // i32
    print_type_of(&main); // playground::main
    print_type_of(&print_type_of::<i32>); // playground::print_type_of<i32>
    print_type_of(&{ || "Hi!" }); // playground::main::{{closure}}
}

官方文档显示该函数是不稳定版本的,后续可能会发生变化。

可变变量

由于rust定义的变量默认情况下是不可变变量。可以通过 mut 关键字让变量成为可变变量。例如:

fn main() {
    let mut a = 123;
    println!("{}", a);
    a = 456;
    println!("{}", a);
}

使用mut修饰之后的变量a,可以在后续的过程中进行重新绑定。这段代码执行的结果是:

123
456

变量默认是不可变的这一点,是 Rust 提供给你的众多优势之一,让你得以充分利用 Rust 提供的安全性和简单并发性来编写代码。

使用下划线开头忽略未使用的变量

如果你创建了一个变量却不在任何地方使用它,Rust 通常会给你一个警告(不是error,这点和go语言不一样),因为这可能会是个 BUG。如果你需要暂时忽略掉这个警告,可以让变量以下划线开头,例如:

fn main() {
    let a = 1;
    let b = 2;
    println!("{}", a);
}

使用cargo run执行这段代码,输出如下所示:
在这里插入图片描述
rust这个编译器是真的非常智能,它警告你,未使用变量b并且给出了解决方案,在b前面加上前缀_即可。让我们加上前缀在来试试。
在这里插入图片描述
rust对于未使用的变量只是给出警告,而不像go语言那样未被使用的变量是会报错的。只是个警告这一点非常方便我们进行调试,如果在go语言中,就不太方便调试。

变量遮蔽(shadowing)

Rust 允许声明相同的变量名,在后面声明的变量会遮蔽掉前面声明的。例如:

use::std::io;

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

fn main() {
    println!("Please input a number:");     // 输出提示
    
    let mut num = String::new();    // 定义一个名为num的String类型的可变变量
    io::stdin().read_line(&mut num).expect("Failed to read line");  // 从标准输入读取一行内容,保存到num中
    print_type_of(&num);            // 打印数据类型
    let num: i32 = match num.trim().parse() {   // 将String类型的num转为i32类型的num,注意这里使用let再次声明num,并让num绑定一个i32数据
        Ok(num) => num,
        Err(_) => {
             println!("请输入整数,请勿输入无关符号!");
             return;
        }
    };
    print_type_of(&num);            // 打印数据类型
    println!("number is {num}");    // 输出数字。
}

执行上面这段代码,打印结果如下所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/7ebd6e1028ef4f3cbd27f544cb841867.gi
可以看到,前后两次num的数据类型发生了变化。这段代码先将一个空字符串(String::new())绑定到变量num上,因此我们第一次打印变量num的数据类型是“alloc::string::String”,接下来,代码从标准输入读取一行内容存放到num中(修改了原来的空字符串)。接着将字符串num转为i32值然后重新绑定到num上,这就导致num的数据类型变为了i32。

像上面的场景,从标准输入读取的数字是字符串类型,但是我希望它是i32类型。变量覆盖避免了像num_str这样的名称,你可以重新绑定到新的值上,而不必去给变量起一个复杂的名称;也避免了大量含义不明的tmp变量或者是xxx_tmp变量这样的名称。

变量遮蔽会涉及一次内存对象的在分配,而不像mut变量那样,它是在原来的内存上做修改。

常量

变量的值不能更改可能让你想起其他另一个很多语言都有的编程概念:常量(constant)。与不可变变量一样,常量也是绑定到一个常量名且不允许更改的值,但是常量和变量之间存在一些差异:

  • 常量不允许使用 mut。常量不仅仅默认不可变,而且自始至终不可变,因为常量在编译完成后,已经确定它的值。(因此,rust里的常量和C/C++中的宏非常类似,它要求在编译期是确定的,而不可变变量的值可以在运行时确定。)
  • 常量使用 const 关键字而不是 let 关键字来声明,并且值的类型必须标注。

Rust 常量的命名约定是全部字母都使用大写,并使用下划线分隔单词,另外对数字字面量可插入下划线以提高可读性,如果未遵守命名规范,rust会给出警告信息。如下所示:
在这里插入图片描述
警告信息告诉我们应该将常量max_num变为大写的名称,并且在给出了帮助信息,提示我们将max_num改为MAX_NUM。rust编译器真的非常友好。

参考资料

  • rust圣经
  • rust程序设计语言

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

路由器的工作原理,详细介绍

1、路由器的作用 路由器&#xff1a; router 作用&#xff1a;实现跨网段通信&#xff0c;不同的网络之间通信 交换机&#xff1a; switch 作用&#xff1a;组建局域网&#xff0c;就是将电脑通过网络连起来 交换机的原理参考文档&#xff1a;计算机网络之交换机的工作原理…

前端React项目的Next.js项目通过CSS引入自定义字体文件

最近在Web3的项目&#xff0c;需要引入自定义字体&#xff0c;做下记录&#xff1a; 1、 如果是下载的字体文件&#xff0c;直接能使用的就不需要转换&#xff0c;如果是TTF格式则需要转换成eot、svg、woff、woff2&#xff0c;这里提供一个网站Font Squirrel | Create Your Ow…

ROS之话题通信

文章目录理论模型分析流程1. 发布方2. 订阅方3.配置 CMakeLists.txt4.执行5.注意参考理论模型 话题通信实现模型是比较复杂的&#xff0c;该模型如下图所示,该模型中涉及到三个角色: ROS Master (管理者)Talker (发布者)Listener (订阅者) ROS Master 负责保管 Talker 和 Li…

简化javabean开发-->Lombok

目录 一.Lombok 1.Lombok 介绍 1.1Lombok 作用 1.2SpringBoot 和 IDEA 官方支持 2.Lombok 常用注解 3.Lombok 应用实例 3.1在 pom.xml 引入 lombok 3.2. 修改 Furn.java 3.3在 idea 安装 lombok 插件 一.Lombok 1.Lombok 介绍 1.1Lombok 作用 1. 简化 JavaBean 开…

Camtasia2023喀秋莎录屏软件下载操作教程

Camtasia软件2023最新版是一款电脑屏幕录制与视频剪辑的软件&#xff0c;功能强大且操作简单。可以使用该软件对视频进行添加滚动字幕的效果&#xff0c;并且还可以选择注释标注的样式、主题以及形状等。在内置的视频编辑器中对视频进行剪辑时还可以拖放文本、添加效果、添加过…

VTK-vtkImplicitFunction及其子类介绍

简介&#xff1a;本文主要介绍vtkImplicitFunction接口及其子类的实现原理和用途。 目录 1. vtkPlane 2. vtkPolyPlane 1. vtkPlane 描述&#xff1a;vtkPlane提供了各种平面的计算方法&#xff0c;包括点到面的投影&#xff0c;计算点到面的距离及面的法向量等。 Evaluat…

解析分布式数据库的技术框架及其在金融行业中的应用规划

早期银行业务系统处理的主要是交易型数据,数据量较少,传统关系型数据库(如Oracel、DB2等)已足够应对。随着互联网金融业务的快速发展,业务系统需要处理的数据呈爆炸式增长,传统数据库无法满足业务系统越来越高的数据处理能力要求。于是,新型的分布式数据库系统应运而生。…

Linux安装Redis 手把手教程

文章目录安装步骤1. 创建安装目录/usr/local/redis2. 进入安装包目录3. 编译环境准备&#xff1a;4. 下载redis 源码包5. 解压文件6. 进入到解压好的redis-5.0.2目录下&#xff0c;进行编译与安装7. 启动并指定配置文件8. 配置允许远程连接&#xff08;选做&#xff09;9. 启动…

文献|敬畏这种情绪,居然可以让世界变得更美好

Hello&#xff0c;大家好~ 这里是壹脑云科研圈&#xff0c;我是青书~ 在介绍今天推荐的文献之前&#xff0c;要先和大家宣布一个非常棒的消息&#xff0c;我们的第二季21天情绪文献对赌营圆满结营啦~ 在本期活动里&#xff0c;各位参加的小伙伴都有属于自己的收获&#xff1…

容器基础镜像的编写及最佳实践

1 基本概念 1.1 Docker系统组成 整体Docker的系统包括以下主要组成部分,包括Dockerclient、Dockerdaemon、Docker registry、Docker镜像、Docker容器,他们之间的关系如下图: Docker架构主要分为客户端和服务端,客户端负责发起请求,服务端负责接受,解析和处理请求,图示中…

【Linux】操作题大全

目录 1.若下达 # rmdir test 命令来删除某个已存在的目录&#xff0c;但无法成功&#xff0c;请说明可能的原因 2.请用shell中的while循环输出1-100的和 两种执行bash文件的方法 3. 请用shell中的for循环输出1-100 4.请用shell中的while循环输出1-100 5.计算输入的参数1和参…

jquery中 offset()计算的偏移量 和 原生Dom计算的偏移量不一致;

目录 一、问题 二、原因及解决方法 三、总结 一、问题 1.需求&#xff1a;有一个表格&#xff0c;单元格宽度不相等&#xff0c;单元格上面覆盖着一个input输入框。想要通过相对位置计算 输入框到底在表格的第几列。 思路&#xff1a;通过循环表格第一行单元格计算左边偏移…

Twitter群推王:推特全方位营销利器

Twitter群推王是专为Twitter运营提供的一款全方位营销工具&#xff0c;可以自动发帖、自动私信、自动转发、自动关注、自动点赞、自动改资料、自动注册、数据采集等&#xff0c;解决营销中的三大难题&#xff1a;账号问题、同一Ip环境问题、批量自动化问题&#xff0c;是个人、…

【数据结构Note4】-串、数组和广义表(kmp算法详解)

串、数组和广义表 顺序表和链表分别是线性表的两种存储结构。 栈和队列是操作受限的线性表。 串、数组和广义表是内容受限的线性表。 1. 串 1.1 串的概念和结构 串&#xff08;String&#xff09;—零个或多个任意字符组成的有限序列 所谓串是内容受限的线性表。就是要求该线性…

[ 常用工具篇 ] 解决kali英文操作不方便的问题 -- kali 设置中文界面

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

iNFTnews|FTX一夜崩塌,但Web3仍前途光明

元宇宙的日子越来越不好过了。 FTX的暴雷仍在产生广泛的影响&#xff0c;以太坊的价格快跌到1000美元了&#xff0c;这与去年11月4900美元的历史新高形成鲜明对比。 不过&#xff0c;尽管市场低迷&#xff0c;创作者仍然在Web3领域找到了爱与支持&#xff0c;甚至是可持续发展…

正则表达式快速入门

目录1.正则表达式是什么&#xff0c;有什么作用2.定位符例子2.1想要搜索以“001”开头的文件2.2想要搜索以“ab”结尾的文件2.3搜索单词开头为“zh"的文件2.4搜索单词结尾为“zh"的文件2.5搜索单词中间为“zh"的文件3.限定符例子3.1 搜索以“0”开头&#xff0c…

【Call for papers】DSN-2023(CCF-B/软件工程/2022年12月7日截稿)

文章目录1.会议信息2.时间节点3.论文主题On behalf of the Organizing Committee, we extend you a warm welcome to the 53rd Annual IEEE/IFIP International Conference on Dependable Systems and Networks (DSN 2023), organized by the University of Coimbra, Portugal.…

MyBatis-Plus 联表查询

文章目录前言引入依赖数据准备修改 Mapper查询分页查询前言 它的联表查询能力一直被大家所诟病。一旦遇到 left join 或 right join 的左右连接&#xff0c;你还是得老老实实的打开 xml 文件&#xff0c;手写上一大段的 sql 语句。 直到前几天&#xff0c;偶然碰到了这么一款…

麻了,3个offer不知道选哪个?

有的小伙伴苦于没offer&#xff0c;有的小伙伴苦于offer多&#xff0c;不知道选择哪个&#xff1f; 本科双非&#xff0c;硕士末端985&#xff0c;拿到了三个offer&#xff0c;过来问小孟去哪&#xff1f; 一&#xff0c;拿到三个不错的offer&#xff1a; 三个offer分别是阿里…