Rust 基础

文章目录

  • 一、变量
    • 1.1 不可变变量/可变变量/常量
    • 1.2 变量的可覆盖性
  • 二、数据类型
    • 2.1 数据类型 & 编译器自动推导机制
    • 2.2 标量与复合
  • 三、函数
    • 3.1 普通函数
    • 3.2 匿名函数/闭包
    • 3.3 函数指针
    • 3.4 高阶函数
    • 3.5 函数部分完整代码:

一、变量

1.1 不可变变量/可变变量/常量

Rust 既支持静态变量也就是不可变的变量,也支持普通的可变变量,声明变量使用 let 关键字,使用 let 声明的变量就是不可变的;再加上 mut 关键字就成了可变变量;
测试一下:
在这里插入图片描述

可以看到对let 变量再次赋值时编译器会给出错误提示; 而 mut 变量则不会;
其实“不可变的变量”和常量是一个意思,但是没管他叫常量是因为 Rust 中除了不可变变量还有常量的概念,对应的关键字是 const
常量不光默认不可变,它总是不可变,也就是常量无法通过 mut 关键字改变属性,这也就是常量和不可变变量的区别。声明常量使用 const 关键字而不是 let,并且 必须 注明值的类型。
,常量在声明它的整个作用域之中都有效,此属性使得常量可以作为多处代码使用的全局范围的值,例如一个游戏中所有玩家可以获取的最高分或者光速。
将遍布于应用程序中的硬编码值声明为常量,也能帮助后来的代码维护人员了解值的意图。如果将来需要修改硬编码值,也只需修改汇聚于一处的硬编码值。
下面这两行用着是一样的

let _via = 6; 
const _const_via = 6; 

其实这些概念和C++真的都很像,学过C++的大多数人应该都是简单看一眼就能理解

1.2 变量的可覆盖性

Rust 支持变量的覆盖,也就是可以定义一个与之前变量同名的新变量,此时一般称之为第一个变量被第二个隐藏(Shadowing) 了,这意味着当使用这个变量的名称时,编译器将使用第二个变量。实际上,第二个变量“覆盖”了第一个变量,此时任何使用该变量名的行为中都会视为是在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。可以用相同变量名称来隐藏一个变量,以及重复使用 let 关键字来多次隐藏,如:
在这里插入图片描述

隐藏与将变量标记为 mut 是有区别的。当不小心尝试对变量重新赋值时,如果没有使用 let 关键字,会导致编译时错误。通过使用 let,我们可以用这个值进行一些计算,不过计算完之后变量仍然是不可变的。
mut 与隐藏的另一个区别是,当再次使用 let 时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字。例如,假设程序请求用户输入空格字符来说明希望在文本之间显示多少个空格,接下来我们想将输入存储成数字(多少个空格):

    let spaces = "   ";let spaces = spaces.len();

关于这个“覆盖”性质我猜测就是遇到再次定义同名变量时就回收前一个变量然后重新 new 一个同名变量,搜了一下 Rust 是有指针的,就把两个变量地址输出对比了一下,发现确实地址不一样,所以我的猜测应该是对的:
在这里插入图片描述

二、数据类型

2.1 数据类型 & 编译器自动推导机制

Rust 是 静态类型(statically typed)语言,每一个值都必须属于某一个 数据类型(data type),也就是说在编译时就必须知道所有变量的类型,才能让 Rust 明确数据处理方式。
不过有时根据值及其使用方式,编译器可以推断出我们想要用的类型,比如前面截图上变量声明后面灰色的 i32 usize, 这两个就是变量类型, 灰色表示是编译器自动推导出来的而非开发者主动指定的。
不过如果当一个变量多种类型均有可能时或编译器无法自动推导出类型时,就必须增加类型注解,像这样:
在这里插入图片描述

建议写代码时都一定要主动指定数据类型,而不要靠编译器推导;

2.2 标量与复合

Rust 的变量支持两类数据类型子集:标量(scalar)和复合(compound)。
标量(scalar)类型代表一个单独的值,比如前面的代码中的变量都是标量类型的,变量都是只有一种类型。比如整数类型i32, 浮点数类型f64,布尔类型bool等。以下是一些常见的标量类型:

* i8: 8位有符号整数
* i16: 16位有符号整数
* i32: 32位有符号整数
* i64: 64位有符号整数
* isize: 平台相关的有符号整数
* u8: 8位无符号整数
* u16: 16位无符号整数
* u32: 32位无符号整数
* u64: 64位无符号整数
* usize: 平台相关的无符号整数
* f32: 32位浮点数
* f64: 64位浮点数
* char: 字符类型
* bool: 布尔类型

注意:
1.isize 和 usize 依赖计算机架构:64 位上是 64 位的,32 位上是 32 位。
2.多种数字类型的数字字面值允许使用类型后缀,例如 57u8 来指定类型,同时也允许使用 _ 做为分隔符以方便读数,例如1_000,它的值与你指定的 1000 相同。
3.当给一个变量赋值为超出它的数据类型数据范围的值时,这种错误称为 “整型溢出”(“integer overflow” ), Rust在debug版下遇到这种问题程序会因错误而退出,而release版会进行一种被称为二进制补码 wrapping(two’s complement wrapping)的操作。简而言之,比此类型能容纳最大值还大的值会回绕到最小值。

复合类型(Compound types)可以将多个值组合成一个类型。Rust 有两个原生的复合类型:元组(tuple)和数组(array)。例如数组类型[i32; 3],元组类型(i32, f64),以及结构体类型struct Point { x: i32, y: i32 }等。以下是一些常见的复合类型:

* [T; N]: 长度为N的数组类型,元素类型为T。数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,Rust 中的数组长度是固定的。
* (T1, T2, ..., Tn): 元组类型,包含n个元素,元素类型分别为T1, T2, ..., Tn.元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定:一旦声明,其长度不会增大或缩小。
* struct S { field1: T1, field2: T2, ..., fieldn: Tn }: 结构体类型,包含n个字段,字段类型分别为T1, T2, ..., Tn。

代码示例:
在这里插入图片描述

三、函数

Rust 中,函数是一段可重用的代码块,用于执行特定任务。
在 Rust 中,函数定义使用 fn 关键字,后跟参数列表和函数名以及返回值类型(可缺省)。参数列表中的每个参数都要有一个类型注解。函数体以大括号{}包围,可以包含多个语句。如:

fn function_name(param1: Type1, param2: Type2) -> ReturnType {// TODO 
}

3.1 普通函数

通过输入 fn 后面跟着函数名和一对圆括号来定义函数,大括号标明函数体的开始和结尾。
需要注意的是在 Rust 中,函数的返回值等同于函数体最后一个表达式的值。使用 return 关键字和指定值,可从函数中提前返回;但大部分函数隐式的返回最后的表达式。
这里提一下**“表达式” 与 “语句” 的差别**:

* 语句(Statements)是执行一些操作但不返回值的指令。 
* 表达式(Expressions)计算并产生一个值。让我们看一些例子。

具体示例参考最下面的代码截图中的 add 与 add2 函数的声明与使用;

3.2 匿名函数/闭包

Rust支持匿名函数,也称为闭包。闭包是一个可以捕获其环境中变量的函数。闭包的定义使用||符号,后跟参数列表和函数体。如:

    let closure = || {// 函数体};

具体示例参考最下面的代码截图中的 add3 函数的声明与使用;

3.3 函数指针

Rust支持函数指针,可以将函数作为值传递给其他函数或存储在数据结构中。函数指针的类型为fn() -> ReturnType。
如:

fn function_name() -> ReturnType {// 函数体
}
let function_pointer: fn() -> ReturnType = function_name; // 将函数赋值给函数指针

具体示例参考最下面的代码截图中的 add4 函数的声明与使用;

3.4 高阶函数

高阶函数是指接受其他函数作为参数或返回其他函数作为结果的函数。在Rust中,可以使用泛型来实现高阶函数。

具体示例参考如下的代码截图中的 add5 函数的声明与使用:
在这里插入图片描述

3.5 函数部分完整代码:

// 定义一个接受两个整数参数并返回它们的和的函数:
fn add(a: i32, b: i32) -> i32 {return a + b
}
fn add2(a: i32, b: i32) -> i32 {a + b
}fn main() {println!("Hello, world!");// 普通函数测试{ let _add_result : i32= add(1, 2);let _add_result1 : i32= add2(1, 2);println!("函数add结果: {_add_result}; 不指定返回值时add函数结果:{_add_result1} ");}// 匿名函数(闭包){// 定义一个闭包,它接受两个整数参数并返回它们的和let add3 = |a: i32, b: i32| a + b;let _add_result : i32 = add3(1, 2);println!("闭包函数add3结果: {_add_result}; ");}// 函数指针{// 定义一个返回和的函数,并将其地址赋给一个函数指针:fn add4(a: i32, b: i32) -> i32 {a + b}let add4_ptr: fn(i32, i32) -> i32 = add4;let _add_result : i32 = add4_ptr(1, 2);println!("函数指针add4结果: {_add_result}");}// 高阶函数{// 定义一个高阶函数,接受一个函数作为参数,并返回一个新的函数fn high_function(func: impl Fn(i32, i32) -> i32) -> impl Fn(i32, i32) -> i32 {move |a, b| func(a, b)}// 定义一个简单的函数,用于计算两个整数的和fn add5(a: i32, b: i32) -> i32 {a + b}// 使用高阶函数let doubled_add = high_function(add5);let _add_result : i32 = doubled_add(1, 2);println!("高阶函数调用add5结果: {_add_result}");}
}

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

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

相关文章

自定义安装Redhat8.6镜像:

目录 一、创建虚拟机 二、选择需要安装的镜像 三、选择正确的操作系统和版本 四、更改虚拟机名称和位置 五、配置处理器和内核数量以及内存 配置规则: 六、网络类型、I/O控制类型、磁盘类型使用推荐 即可 网络类型: I/O控制类型: 磁盘类型: 七…

报道 | 2023-2024年1月国际运筹优化会议汇总

2023年10月、11月、12月召开会议汇总: 2023 International Conference on Optimization and Applications (ICOA) Location: Abu Dhabi, United Arab Emirates Important dates: Conference: October 05-06, 2023 Details: https://lct.ac.ae/en/icoa/ 2023 INF…

21GA-ELM,遗传算法优化ELM预测,并和优化前后以及真实数值进行对比,确定结果,基于MATLAB平台,程序已经调通,可以直接运行,需要直接拍下。

GA-ELM,遗传算法优化ELM预测,并和优化前后以及真实数值进行对比,确定结果,基于MATLAB平台,程序已经调通,可以直接运行,需要直接拍下。 21matlab时间序列预测极限学习遗传优化算 (xiaohongshu.co…

【算法|前缀和系列No.1】牛客网 DP34 【模板】前缀和

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【牛客网刷题】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希…

如何从 Pod 内访问 Kubernetes 集群的 API

Kubernetes API 是您检查和管理集群操作的途径。您可以使用Kubectl CLI、工具(例如curl)或流行编程语言的官方集成库来使用 API 。 该 API 也可供集群内的应用程序使用。Kubernetes Pod 会自动获得对 API 的访问权限,并且可以使用提供的服务帐户进行身份验证。您可以通过使…

19 | 如何搞清楚事务、连接池的关系?正确配置是怎样的

事务的基本原理 在学习 Spring 的事务之前,你首先要了解数据库的事务原理,我们以 MySQL 5.7 为例,讲解一下数据库事务的基础知识。 我们都知道 当 MySQL 使用 InnoDB 数据库引擎的时候,数据库是对事务有支持的。而事务最主要的作…

Elasticsearch实现检索词自动补全(检索词补全,自动纠错,拼音补全,繁简转换) 包含demo

Elasticsearch实现检索词自动补全 自动补全定义映射字段建立索引测试自动补全 自动纠错查询语句查询结果 拼音补全与繁简转换安装 elasticsearch-analysis-pinyin 插件定义索引与映射建立拼音自动补全索引测试拼音自动补全测试繁简转换自动补全 代码实现demo结构demo获取 自动补…

【c语言】迷宫游戏

之前想写的迷宫游戏今天终于大功告成,解决了随机生成迷宫地图的问题,使用的是深度优先算法递归版本,之前的迷宫找通路问题用的是深度优先算法的非递归实现.之前写过推箱子,推箱子用到了人物的移动,以及碰到墙就不会走&…

【ALO-BP预测】基于蚁狮算法优化BP神经网络回归预测研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Python学习----Day08

函数变量的作用域 全局作用域 全局作用域在程序执行时创建,在程序执行结束时销毁。所有函数以外的区域都是全局作用域。在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问。 函数作用域 函数作用域在函数调用…

【Eclipse】解决插件下载速度太慢

解决方案:修改镜像 下面列出几个国内的镜像网站: 中国科学技术大学(5.6MB/s) http://mirrors.ustc.edu.cn/eclipse/ 北京理工大学(600KB/s) http://mirror.bit.edu.cn/eclipse/ 大连东软信息学院(400KB/s) http://mirrors.neuso…

Linux网络编程系列之服务器编程——阻塞IO模型

Linux网络编程系列 (够吃,管饱) 1、Linux网络编程系列之网络编程基础 2、Linux网络编程系列之TCP协议编程 3、Linux网络编程系列之UDP协议编程 4、Linux网络编程系列之UDP广播 5、Linux网络编程系列之UDP组播 6、Linux网络编程系列之服务器编…

Ubuntu:VS Code IDE安装ESP-IDF【保姆级】

物联网开发学习笔记——目录索引 参考: VS Code官网:Visual Studio Code - Code Editing. Redefined 乐鑫官网:ESP-IDF 编程指南 - ESP32 VSCode ESP-ID Extension Install 一、前提条件 Visual Studio Code IDE安装ESP-IDF扩展&…

读写锁ReentrantReadWriteLockStampLock详解

如何设计一把读写锁?ReentrantReadWriteLock 读写锁设计思路 读写状态的设计 设计的精髓:用一个变量如何维护多种状态 在 ReentrantLock 中,使用 Sync ( 实际是 AQS )的 int 类型的 state 来表示同步状态,表示锁被一个线程重复获…

ChatGPT AIGC 完成Excel跨多表查找操作vlookup+indirect

VLOOKUP和INDIRECT的组合在Excel中用于跨表查询,其中VLOOKUP函数用于在另一张表中查找数据,INDIRECT函数则用于根据文本字符串引用不同的工作表。具体操作如下: 1.假设在工作表1中,A列有你要查找的值,B列是你希望查询的工作表名称。 2.在工作表1的C列输入以下公式:=VLO…

Unity基础课程之物理引擎6-关于物理材质的使用和理解

每个物体都有着不同的摩擦力。光滑的冰面摩擦力很小,而地毯表面的摩擦力则很大。另外每种材料也有着不同的弹性,橡皮表面的弹性大,硬质地面的弹性小。在Unity中这些现象都符合日常的理念。虽然从原理上讲,物体的摩擦力和弹性有着更…

【交付高质量,用户高增长】-用户增长质量保证方法论 | 京东云技术团队

前言 俗话说,“测试是质量的守护者”,但单凭测试本身却远远不够。大多数情况下,测试像“一面镜子”,照出系统的面貌,给开发者提供修改代码的依据,这个“照镜子”的过程,就是质量评估的过程&…

在 VSCode 中使用 PlantUML

最近,因为工作需要绘制一些逻辑图,我自己现在使用的是 PlantUML 或者 mermaid,相比之下前者更加强大。不过它的环境也麻烦一些,mermaid 在一些软件上已经内置了。但是 PlantUML 一般需要自己本地安装或者使用远程服务器&#xff0…

Paddle GPU版本需要安装CUDA、CUDNN

完整的教程 深度学习环境配置:linuxwindows系统下的显卡驱动、Anaconda、Pytorch&Paddle、cuda&cudnn的安装与说明 - 知乎这篇文档的内容是尽量将深度学习环境配置(使用GPU)所需要的内容做一些说明,由于笔者只在windows和linux下操作过&#xf…

浏览器本地存储之Cookie和webStorage

浏览器本地存储主要包括 Cookie 和 Web Storage 两种机制。它们都是用来在客户端存储数据,以便在浏览器会话之间保持信息或在同一会话中的页面之间共享信息。 一、Cookie 1.1 概念 cookie是客户端与服务器端进行会话使用的一个能够在浏览器本地化存储的技术。简言…