Rust基础
一:编译器
Rust的编译器叫rustc,类似javac一样,负责将源代码编译成可执行文件或者库文件(.a/.so/.lib/.dll等)
二:核心库和标准库
Rust语言由核心库和标准库组成,核心库是标准库的基础,核心库不依赖于操作系统和网络相关的库,一般写嵌入式应用会用到;
可以在模块顶部引入#![no_std]来使用核心库;
标准库则一般用来开发应用程序,它提供了开发应用程序所需的基础和跨平台支持,比如println!宏其实就是标准库里的,它依赖操作系统提供的API来实现在标准输出流里打印数据;
三:包管理器
Rust的包管理器是cargo【马车】,而Rust里每个项目编译成的库叫做crate,类似Java里的jar包;
cargo除了是包管理器,它还能用于创建可执行程序项目和库项目,命令分别是:
1.cargo new exec_proj
2.cargo new --lib lib_proj
然后可以通过cargo build和cargo run对项目进行编译和允许;
四:Rust的语句和表达式
Rust里语法可以分为两大类,即语句和表达式;
语句是指分号结尾,或者花括号结尾的代码,比如输出语句,变量声明语句或结构体声明语句等等;
表达式则是指没有分号的表达式,如果它处于某个X块或函数最后一行,那么它将自动作为X块或函数的返回值,比如1 + 1就是一个表达式,放在函数最后表示这里将return 2;
五:变量绑定
变量默认是不可变的,即let a = 3;a = 4;会报错;但是可以通过let mut a = 3;来将a声明为可变的变量;将3赋值给a也叫绑定;a本质上是一个是i32类型指向了3所在空间的地址的一个指针数值;
虽然变量默认是不可变的,但是变量是可以转移/移动所有权的,即let a = M{..};let b = a;此时将a对M{..}对象的所有权转移给了b;【注意,基础类型是复制语义不会移动所有权】
六:指针
其实Rust里变量名,引用,原生指针和智能指针本质上都是指向一块地址空间的起始地址【但是这个指针在Rust编译器里还拥有对应地址空间的大小,空间的结构等数据,但是它编译后则会自动分解成对不同位置进行操作的汇编代码】;
原生指针可以通过let a = 3;let ptr = &mut a as *mut i32;来获取原生指针【原生指针分为可变和不可变原生指针,这里*mut i32就是可变,*const i32就是不可变,可变表示可以对其指向的空间的内容修改,通过*ptr = 8;来实现,即原生指针的解引用(解指针)也是用*】
变量也可以通过变量遮蔽实现同一个作用域定义同名变量,比如let a = 3; let a = "kkk".to_string();
它的作用一般是比如let a = Some(44);let a = a.unwrap();
七:函数、方法和闭包
函数和方法的区别是全局的函数一般就叫函数,而在impl块属于某个结构体的函数叫做方法,比如AClass的test方法(还可以分静态方法或实例方法,实例方法第一个参数是&self或&mut self);
函数和方法的声明都是fn关键字进行声明;
闭包则本质上是一个实现了Fn之类的trait的匿名结构体;
函数和闭包都能作为函数参数或返回值(函数指针fn(i32, i32) -> i32),不同的是,函数无法捕获上下文变量;
Rust有一种const函数,即这个函数可以当做常量来使用,它的值是在编译期间确定的,这个是Rust实现反射的基础,写法为const fn lala() -> i32 {..}
函数可以在函数内部声明;
八:流程控制
条件表达式:和其他语言不同,Rust的if表达式可以返回值,但是注意不同分支返回的值的类型必须一样,如let a = if (...) { 3} else {4}
循环表达式:可以用for i in 0..10 {..}实现类似C语言里for(int i = 0;i<10;i++){..},其中in的参数可以是范围类型(不过0..10应该也是范围类型的简写,少了括号);
还有loop {...}循环【恒真】和while boolean{..}循环;
match表达式:它有点像switch,但是比switch灵活很多,写法为:match variable {0 => ....,1...3 => .....,5 | 7 => .....,_=>.....,},这里对variable变量进行匹配,如果值是0则,是1到3则,是5或7则,其他的则,但是要注意每个分支返回的类型必须相同;
九:类型
数值类型有:u8-u128表示一字节无符号值到16个字节无符号值,对应的还有i8-i128表示有符号;其中还有usize表示是跟机器字长相关的无符号整数;isize则是有符号;
浮点型的则有f32和f64;
字符类型为:char,它占4个字节(UTF-8);
数组类型:[1,2,3]这样的则是数组对象,它的类型定义可以是[i32; 3]前面表示类型,后面表示长度,还能用[1;3]表示长度是3的i32类型(默认是i32)且数组里每个元素初始值为1;
范围类型:用(1..5)表示,注意这种写法是左闭右开,即1,2,3,4,这个和数学上的写法不同;如果是全闭则是(1..=5);
切片类型:貌似就是数组或向量或字符串的引用?
字符串类型:str,它类似Java里的String,是一个字符串常量,长度内容不可变;而Rust里的String则是长度可变的字符串;
never类型:它的类型名叫!,表示一定不会赋值的类型,它感觉上和单元类型很像(单元类型是没什么意义,类似void),比如panic!宏的返回值就是!类型,由于产生了panic所以一定不会返回值,因此这种概念里的返回值类型就是never类型!
元组类型:元组类型是异构且可以解构的类型,用let tuple: (i32, &str) = (3, "bb");这种写法,解构元组则是let (x, y) = tuple;,那么3和"bb"就分别赋值给了x和y;
结构体:分为具名结构体(最常见),元组结构体和单元结构体;
具名结构体写法为struct Peple{name: &str,gender: u32};元组结构体写法为struct Color(i32, i32, i32);,单元结构体则是没有属性的结构体如struct Empty;它等同于struct Empty{}
枚举:枚举有三种形式,分别是无参枚举,类C枚举和类型参数枚举;第一种写法为enum Number {Zero, One},第二种写法为enum Color {Red = 0xff0000},这种的结构体值可以转换为对应的基础类型值;
第三种写法比较特殊,为enum IpAddr {V4(u8, u8, u8, u8)},V4实际上是一个函数类型(不是闭包实现的Fn等的trait,是fn(u8,u8,u8,u8)),枚举值调用方式为Number::Zero;而且枚举值里可以有两种方式,比如enum Option{Some(i32),None},第一个Some(i32)是第三种形式,而None则是第一种形式;
向量:Vec<T>,是容量可变的线性容器,它可以用vec![]初始化一个空向量;用vec![0; 10]初始化一个长度是10初始化值是0的向量;也可以用let mut v3 = Vec::new();来创建一个向量(最好指定类型);
双端队列:VecDeque<T>也是线性容器,它能够从左至右push元素(get为左边最小下标),也能够从右至左push元素;
链表:LinkedList<T>,链表也是类似双端队列,不过它内部是链表来存储元素的;
HashMap<K,V>:K类型必须是可哈希的类型,V类型则必须是在编译期间已知大小的类型;它和Java的API不同,用insert插入元素;它内部存储的元素是无序的,即每次迭代HashMap输出的内容都会不同;
BTreeMap<K,V>:约束同上,但是BTreeMap每次插入元素都会自动按Key的值进行排序;【Rust里貌似没有按插入元素的先后顺序排序的Map】
HashSet<K>:其实就是HashMap将value置为()【单元值】的集合;
BTreeSet<K>:原理同上;
BinaryHeap<T>:优先队列,通过二叉最大堆实现的;
待续。。
Rust基础的更多相关文章
- Rust基础笔记:闭包
语法 Closure看上去是这样的: let plus_one = |x: i32| x + 1; assert_eq!(2, plus_one(1)); 首先创建一个绑定plus_one,然后将它分 ...
- Rust 基础学习
所有权: 变量具有唯一所有权.如果一个类型拥有 Copy trait,一个旧的变量在将其赋值给其他变量后仍然可用.除此之外,赋值意味着转移所有权.Rust 不允许自身或其任何部分实现了 Drop tr ...
- Rust笔记
前言: 学了有段时间了,现在同步到博客园. 正文: Rust语言介绍 l Rust由js之父开发的新型语言,打破了传统的难以接触底层的局面.这是个有C++开发的语言.拥有C的血统 l Rust必须严格 ...
- rust学习
Rust (github) 1. install (https://rustup.rs/) 2. play on line curl https://sh.rustup.rs -sSf | sh e ...
- 创建一个用目录分层的Rust应用
一:前言,这是Rust基础程序,主要是用来讲解怎么创建分层(类似Java package)的应用: 二:代码实现: 2.1在src下创建main.rs,然后声明main方法,代码如下: fn main ...
- CA周记 2022年的第一课 - Rust
现代编程语言有很多,在我的编程学习里面有小学阶段的 LOGO , 中学阶段的 Pascal ,也有大学阶段的 C/C++.Java..NET,再到工作的 Objective-C .Swift.Go.K ...
- 最强肉坦:RUST多线程
Rust最近非常火,作为coder要早学早享受.本篇作为该博客第一篇学习Rust语言的文章,将通过一个在其他语言都比较常见的例子作为线索,引出Rust的一些重要理念或者说特性.这些特性都是令人心驰神往 ...
- Rust Aya 编写 eBPF 程序
本文地址:https://www.ebpf.top/post/ebpf_rust_aya 1. 前言 Linux 内核 6.1 版本中有一个非常引人注意的变化:引入了对 Rust 编程语言的支持.Ru ...
- 《HelloGitHub》第 77 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...
随机推荐
- 严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
十月 30, 2019 11:12:35 下午 org.apache.catalina.core.StandardContext listenerStart 严重: Exception sending ...
- memoryDiary
What did you accomplish today? , did you exercise today? Do you care about the people around you tod ...
- Mophues HDU - 4746 (莫比乌斯反演)
Mophues \[ Time Limit: 10000 ms\quad Memory Limit: 262144 kB \] 题意 求出满足 \(gcd\left(a,b\right) = k\), ...
- vue基于iview树状表格,封装完善
先安装iview后在使用 完善按钮不显示问题 ,当children过多时,点击不动问题等 封装 <template> <div :style="{width:tableWi ...
- .net core 从 ActionFilterAttribute 获取Request.Body 的正确方式
由于 ModelBinding在动作过滤器之前运行,直接使用 context.ActionArguments["parameter"] 获取模型对象 This article s ...
- 构造方法(_ _construct) 和析构方法(__destruct)
构造方法,是一个特殊的方法: 1,名字是固定的:_ _construct: 2,该方法通常都不要我们自己调用,而是在new一个对象的时候会自动调用. 3,该方法主要的目的是为了在new一个对象的时候, ...
- 用户路径分析(User Path Analysis)
什么是用户路径? 用户路径即抽象用户在网站或APP中的访问路径.其可用桑基图展现,称为用户路径图. 什么是用户路径分析? 用户路径分析追踪用户从某个开始事件直到结束事件的行为路径,即对用户流向进行监测 ...
- 04-树5 Root of AVL Tree (25 分)
An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child sub ...
- sql脱库的几种方法
当发现sql注入之后,脱库的方法,有以下几种: (1)当目标主机支持外部连接时,使用Navicat 进行连接!当时目标主机不同,使用的Navicat种类不一样: mysql : Navicat f ...
- 范仁义html+css课程---11、html补充知识
范仁义html+css课程---11.html补充知识 一.总结 一句话总结: 小于号(<):< 大于号(>):> 空格: 二.html 字符实体 1.小于号(<)和大 ...