Rust 快速入门(一)

news2024/11/27 22:45:47

Rust安装信息解释

  • cargo:Rust的编译管理器、包管理器、通用工具。可以用Cargo启动新的项目,构建和运行程序,并管理代码所依赖的所有外部库。

  • Rustc:Rust的编译器。通常Cargo会替我们调用此编译器。

  • Rustdoc:是Rust的文档工具。

基础语法

变量

Rust是强类型语言(JavaC++RustGo ),但是具有自动判断变量类型的能力。

注意:

  • 强类型语言要求每个变量在声明时必须指定明确的数据类型,并且在程序的整个生命周期中都必须遵循这个类型。语言通常会严格限制不同类型之间的隐式转换,只有明确的、兼容的转换才能进行。这种语言有助于减少由于类型不匹配而导致的错误,并且更容易进行静态检查和优化。

  • 弱类型语言对变量的类型要求相对宽松。程序允许对不同类型的变量进行隐式转换,语言运行时会根据需要自动进行类型转换。这虽然提供了更多的灵活性,但也可能带来一些类型转换带来的潜在错误。

声明变量使用 let 关键字

let a = 123;    
let a:u64 = 12;// 带类型的声明

如果上述a被声明了,那么

a = "abc"; // a已经是一个int类型
a = 4.56; // a已经是一个int类型
a = 456; // Rust规范,在语言层面尽量少的让变量的值可以改变

上述三个是被禁止的操作,a被称为不可变变量(a的值不变,但是不代表它不是一个变量),这样操作是为了并发安全。

如果我们要声明一个可变变量,只需加一个 mut关键字

let mut a = 456

那么常量和不可变变量的区别是什么呢?

  • 不可变量如下可编译

    let a = 12;
    let a = 123;

    可编译

    只是有warning。

  • 如果a为常量就不可编译了

    const a: i32 = 123;
    let a = 456;

重影Shadowing

  • 变量的值可以"重新绑定",但在"重新绑定"以前不能私自被改变,这样可以确保在每一次"绑定"之后的区域里编译器可以充分的推理程序逻辑。

  • 这里的重影实际上就是上述“重新绑定”这个概念,重影即指的是变量名称可以被重新使用的机制。

  • 重影与可变变量的赋值不是一个概念,重影是指用同一个名字重新代表另一个变量实体,其类型、可变属性和值都可以变化。但可变变量赋值仅能发生值的变化。

fn main() {
    let x = 5;
    let x = x + 1;
    let x = x * 2;
    println!("The value of x is: {}", x);
}

数据类型

注意:

  • Rust不支持 ++ 和 --

  • 在Rust中,方法的调用优先级高于前缀运算符(对负值进行方法调用时一定要先加负号)

    assert_eq!((-32760_i16).saturating_sub(10), -32768);

    如果这里写成-32760_i16.saturating_sub(10)则该断言一定panic

整数类型

位长度有符号无符号
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
arch(机器字)isizeusize

isize 和 usize 两种整数类型是用来衡量数据大小的,它们的位长度取决于所运行的目标平台,如果是 32 位架构的处理器将使用 32 位位长度整型。

Rust在调用类型本身的方法之前,必须确切的知道一个值属于哪种整型,只有在解析完所有方法之后类型仍然不明确的时候,才会默认位i32。正确示例如下:

 println!("{}", i32::abs(-4));
 println!("{}", (-4_i32).abs());

用于处理溢出的多种整型算术方法:

  1. 检查算法:检查运算会返回结果的 Option 值,如果数学意义上正确的结果可以表示为该类型的值,那么就为Some(v), 否则位None,如:

    assert_eq!(10_u8.checked_add(20), Some(30)); // 可以运行,都处于u8的 0 - 2^8-1(255)范围内
    assert_eq!(100_u8.checked_add(156), None); // 溢出了u8类型,所以会返回 None
  2. 回绕算法:会返回与“数学意义上正确的结果”对“值类型范围”取模的值相等的值,如:

    assert_eq!(100_u16.wrapping_mul(200),20000); // 该行代码可以运行,20000 < u16的65535
    assert_eq!(500_u16.wrapping_mul(500),53392); // 该行代码也可以运行,这是因为250000 > 2^16, 所以会用 250000 % 2^16 最终得到的便是 53392

    需要注意的是对于有符号类型的运算可能会回绕为负值。

  3. 饱和算法:会返回最接近“数学意义上的正确结果”的可表达值(我理解为在计算值res溢出所选类型的最大值时,取所选类型最大值;计算值res所小于类型的最小值时,取所选类型最小值),如:

    assert_eq!(32760_i16.saturating_add(10), 32767);
    assert_eq!((-32760_i16).saturating_sub(10), -32768);

    注意:不存在饱和除法,饱和求余法或饱和位移法

  4. 溢出算法:返回一个元组(result, overflow), result是回绕版本所返回的内容,而overflowed是一个布尔值,指示是否发生过溢出,如:

    assert_eq!(255_u8.overflowing_sub(2), (253, false)); // 未溢出
    assert_eq!(255_u8.overflowing_add(2), (1, true)); // 溢出,返回回绕方法结果 1

浮点数类型

Rust提供了 IEEE 单精度浮点类型和 IEEE 双精度浮点类型。

let x = 2.0; // f64
let y: f32 = 3.0; // f32

浮点类型字面量:

浮点数中整数部分之后的每个部分都是可选的,但是必须存在浮点数部分指数部分类型后缀中的一项。

小数部分也可以由单独.组成,例如 5. 是一个浮点常量。

Rust会将整型字面量和浮点类型字面量视为不同的大类,即它永远不会把整型字面量推断为浮点类型。

一些特殊值关联常量

  • INFINITY:无穷大

  • NEG_INFINITY:负无穷大

  • NAN:非数值

  • MIN:最小有限值

  • MAX:最大有限值

使用示例

assert((-1./f32::INFINITY).is_sign_negative())

布尔类型

true,false

if和while这样的控制结构,他们的条件必须时bool表达式,Rust的as运算符可以将bool转化为整型:

assert_eq!(false as i32, 0)
assert_eq!(true as i32, 1)

字符类型

char

Rust的 char 类型大小为 4 个字节(32位),代表 Unicode标量值(Java 2 字节, c/c++ 1字节)

Rust会对单独的字符使用char类型,但是对于字符串和文本流使用UTF-8编码。(所以String为UTF-8字符序列,而不是类似于Java中的字符数组)

转换

  • 在Rust中字符被视为与数值截然不同的类型:char既不是u8,也不是u32(尽管他确实有32位长)

  • 尽管数值类型和char是不同的,但是Rust位u8值提供了字节字面量,如:b'X'表示以字符X的ASCII作为u8值

  • Rust不会再char和任何其他类型之间进行隐式转换。可以使用as转换运算符将char转换为整型,对于小于32位的类型,该字符值的高位会被截断。

  • u8是唯一能够通过as运算符转换为char的类型,因为Rust刻意让as运算符只执行开销极低且可靠的转换。

复合类型

  • 元组:一对 ( ) 包括的一组数据,可以包含不同种类的数据

    let tup: (i32, f64, u8) = (500, 6.4, 1);
    // tup.0 等于 500
    // tup.1 等于 6.4
    // tup.2 等于 1

    Rust代码通常会使用元组类型从一个函数返回多个值(这里很像golang原生提供的多个返回值的特性),如:

    let text = "我是米卫兵,我喜欢完原神,我也喜欢玩星穹铁道";
    let(head, tail) = text.split_at(15);
    println!("{}", head);
    println!("{}", tail);

    零元组:又被称为 单元类型 ,用于:当无法携带任何有意义的值,但是其上下文仍然要求传入某种类型时。如:

    fn swap<T>(x: &mut T, y: &mut T);
    // 上者完整写法如下:
    fn swap<T>(x: &mut T, y: &mut T) -> ();

    还有一个点,需要注意:在使用单个值的元组的时候一定要追加尾逗号 ("hello",),如此一来便可区分普通括号表达式和元组。

  • 数组,和go类似,但是需要注意的几点如下

    • let d = [3; 5]; // 这样声明数组等效于 let d = [3, 3, 3, 3, 3];
    • 然后就是 mut 这个关键字,与不可变变量概念类似,只有一个数组声明了mut后,其中元素才可以被修改。

区别:

  • 元组中每个元素都可以有不同的类型,而数组中所有元素必须是相同的类型。

  • 元组只允许使用常量作为索引。如:t.1, t.2 而不能使用 t.i

指针类型

不同于大多数具有垃圾回收机制的语言,Rust会将内存分配保持在最低限度。默认情况下会嵌套,三种指针类型:

引用

&String => 读作 “ref String” 是对String类型的引用。表达式 &x 会生成一个对x的引用,在Rust

术语中,我们会说它借用了对x的引用。给定一个引用r,表达式 *r会引用r指向的值。

  • 与c/cpp类似:

    • 当超出作用域时,引用不会自动释放任何资源。

  • 与c/cpp不同:

    • Rust的引用永远不位空。

    • Rust会跟踪值的所有权和生命周期。

如此一来,Rust在编译期就可以排除悬空指针、双重释放和指针失效等错误。

Rust引用两种形式
  • &T

    • 一个不可变共享引用。

  • mut T

    • 一个可变的、独占引用。

Box

堆种分配内存最简单的方式:Box::new,如:

let t = (12, "eggs");
let b = Box::new(t)
// t类型为(i32, &str) => b类型为Box<i32, &str>

当b超出作用域时,内存会立即被释放,除非b已经被移动(move)。

不安全指针(裸指针)

  • *mut T

  • *const T

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

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

相关文章

Java 面向对象设计一口气讲完![]~( ̄▽ ̄)~*(上)

目录 Java 类实例 Java面向对象设计 - Java类实例 null引用类型 访问类的字段的点表示法 字段的默认初始化 Java 访问级别 Java面向对象设计 - Java访问级别 Java 导入 Java面向对象设计 - Java导入 单类型导入声明 按需导入声明 静态导入声明 例子 Java 方法 J…

decltype推导规则

decltype推导规则 当用decltype(e)来获取类型时&#xff0c;编译器将依序判断以下四规则&#xff1a; 1.如果e是一个没有带括号的标记符表达式(id-expression)或者类成员访问表达式&#xff0c;那么decltype(e)就是e所命名的实体的类型。此外&#xff0c;如果e是一个被重载的函…

k8s 之安装metrics-server

作者&#xff1a;程序那点事儿 日期&#xff1a;2024/01/29 18:25 metrics-server可帮助我们查看pod的cpu和内存占用情况 kubectl top po nginx-deploy-56696fbb5-mzsgg # 报错&#xff0c;需要Metrics API 下载 Metrics 解决 wget https://github.com/kubernetes-sigs/metri…

基于auth2的单点登录原理理解

创作背景&#xff1a;基于auth2实现企业门户与业务系统的单点登录跳转。 架构组成&#xff1a;4A统一认证中心&#xff0c;门户系统&#xff0c;业务系统&#xff0c;用户&#xff1b; 实现目标&#xff1a;用户登录门户系统后&#xff0c;可通过点击业务系统菜单&#xff0c…

字符串数学专题

粗心的小可 题目描述 小可非常粗心&#xff0c;打字的时候将手放到了比正确位置偏右的一个位置&#xff0c;因此&#xff0c;Q打成了W&#xff0c;E打成了R&#xff0c;H打成了J等等。键盘如下所示 现在给你若干行小可打字的结果&#xff0c;请你还原成正确的文本。 输入描述…

嵌入式面试八股文(五)·一文带你详细了解程序内存分区中的堆与栈的区别

目录 1. 栈的工作原理 1.1 内存分配 1.2 地址生长方向 1.3 生命周期 2. 堆的工作原理 2.1 动态内存分配 2.1.1 malloc函数 2.1.2 calloc函数 2.1.3 realloc函数 2.1.4 free函数 2.2 生命周期管理 2.3 地址生长方向 3. 堆与栈区别 3.1 管理方式不同…

海南聚广众达电子商务咨询有限公司助力商家业绩飙升

在这个短视频与直播风靡的时代&#xff0c;抖音电商无疑成为了众多商家竞相追逐的新风口。作为电商服务领域的佼佼者&#xff0c;海南聚广众达电子商务咨询有限公司凭借其专业的团队、创新的策略与丰富的实战经验&#xff0c;正引领着一批又一批商家在抖音平台上破浪前行&#…

顺序表及其代码实现

目录 前言1.顺序表1.1 顺序表介绍1.2 顺序表基本操作代码实现 总结 前言 顺序表一般不会用来单独存储数据&#xff0c;但自身的优势&#xff0c;很多时候不得不使用顺序表。 1.顺序表 1.1 顺序表介绍 顺序表是物理结构连续的线性表&#xff0c;支持随机存取&#xff08;底层…

Leetcode—139. 单词拆分【中等】

2024每日刷题&#xff08;173&#xff09; Leetcode—139. 单词拆分 dp实现代码 class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {int n s.size();unordered_set<string> ust(wordDict.begin(), wordDict.end());vector<b…

探索基于基于人工智能进行的漏洞评估的前景

根据2023年的一份报告 网络安全企业据估计&#xff0c;到 10.5 年&#xff0c;网络犯罪每年将给世界造成 2025 万亿美元的损失。每年记录在案的网络犯罪数量都会创下新高。这要求对传统的安全测试流程进行重大改变。这就是漏洞评估发挥作用的地方。 漏洞评估对于识别系统中的弱…

双指针_有效三角形个数三数之和四数之和

有效三角形个数 思路&#xff1a; 我们可以通过暴力枚举&#xff0c;三重for循环来算但&#xff0c;时间复杂度过高。 有没有效率更高的算法呢&#xff1f; 我们知道如果两条较短的边小于最长的一条边&#xff0c;那么就可以构成三角形。 如果这个数组是升序的&#xff0c;两…

负压DC-DC开关电源设计

负压DC-DC开关电源设计 与常见的正压输出BUCK电路对比&#xff0c;区别就在于将 原芯片接GND的网络接到了负压输出。 电感一接sW引脚&#xff0c;另外一接到了OV-GND。 注意几点如下: 芯片耐压选择 EN引脚耐压 输入滤波电容的选择 拓扑结构 BOOST模式&#xff1a;当NMO…

NXP i.MX8系列平台开发讲解 - 4.2.3 摄像头篇(三) - 摄像头MIPI 接口

专栏文章目录传送门&#xff1a;返回专栏目录 Hi, 我是你们的老朋友&#xff0c;主要专注于嵌入式软件开发&#xff0c;有兴趣不要忘记点击关注【码思途远】 文章目录 关注星号公众号&#xff0c;不容错过精彩 作者&#xff1a;HywelStar 1. 概述 MIPI是Mobile Industry Pr…

论文阅读:InternVL v1.5| How Far Are We to GPT-4V? 通过开源模型缩小与商业多模式模型的差距

论文地址&#xff1a;https://arxiv.org/abs/2404.16821 Demo&#xff1a; https://internvl.opengvlab.com Model&#xff1a;https://huggingface.co/OpenGVLab/InternVL-Chat-V1-5 公开时间&#xff1a;2024年4月29日 InternVL1.5&#xff0c;是一个开源的多模态大型语言模…

【无人机设计与控制】基于matlab的无人机FMCW(频率调制连续波)毫米波高度计雷达仿真

摘要 本文介绍了一种基于FMCW&#xff08;频率调制连续波&#xff09;雷达技术的无人机毫米波高度计的仿真。FMCW雷达通过测量发射信号与回波信号之间的频差来确定目标的距离和速度。在本项目中&#xff0c;我们使用MATLAB仿真无人机毫米波雷达的性能&#xff0c;展示其在不同…

TS1 order set分析

如下图&#xff0c;所示为TS1 order序列。该序列有16个symbol组成。 常见的symbol有&#xff0c;PAD和COM等。PAD是K symbol&#xff0c;还有D symbol。下文先给出COM symbol的解读。读协议文档可知COM常被称为K28.5。K是symbol的类型&#xff0c;注意symbol是编码过的数据。K…

六、Java 基础语法(下)

一、变量 1、变量的定义与使用 变量就是内存中的存储空间&#xff0c;空间中存储着经常发生改变的数据变量定义格式&#xff1a; 数据类型 变量名 数据值使用时根据变量名使用举例如下&#xff0c;上面是代码&#xff0c;下面是输出 2、变量的注意事项 变量名不允许重复…

Dyna-slam复现(保姆级详细图文版,百分百成功)

因最近论文要和这些算法做对比,故配置了一下,在此记录 因为是老的算法,cuda版本现在的显卡都不能使用,所以笔者找的电脑是华硕飞行堡垒17年的电脑,1080的显卡 深度学习及maskrcnn配置 先将dyna-slam git下来,终端执行 git clone https://github.com/BertaBescos/Dyna…

Arduino UNO R3自学笔记21 之 Arduino电机的闭环控制

注意&#xff1a;学习和写作过程中&#xff0c;部分资料搜集于互联网&#xff0c;如有侵权请联系删除。 前言&#xff1a;上篇写了电机速度测定&#xff0c;这篇主要是讲测定出的速度用于反馈&#xff0c;使得实际速度快速响应到需要的速度。 1.控制系统介绍 分2大类&#x…

ECML PKDD 2024 | 时空数据(Spatial-Temporal)和时间序列(Time series)论文总结

ECML PKDD 2024于9月9号-9月13号在立陶宛维尔纽斯举行&#xff08;Vilnius&#xff09; 本文总结了ECML PKDD 2024有关时空数据&#xff08;spatial-temporal data&#xff09;的相关论文&#xff0c;主要包含交通预测&#xff0c;预训练&#xff0c;迁移学习等内容&#xff0…