Rust 学习笔记3
写在前面
本章记录了rust中使用包,crate,模板以及常见的集合数据类型
Rust学习笔记2
Rust学习笔记1
chapter 6 使用包&crate&模块
6.1 包和crate
6.1.1 模块系统
自顶向下
- package
- crate
- module use
- path
6.1.2 crate
- binary/library
- crate root是rust编译器开始的地方
- 一个package至少包含一个crate
- 一个binary crate和一个library crate可以共存
- package可以有 多个binary crate
6.1.3 module
- 将代码进行分组
- 使用mod关键字
- mod可以进行嵌套
- rust中默认私有,加了pub关键字就是公共的
- 父级模块无法访问子模块中的私有模块
- 子模块可以访问父级模块中的私有模块
- struct前面加上pub,表示struct公有,但是字段默认私有的
- enum是pub,则其子字段也是公有的
6.2 path
- 绝对路径:从crate root开始→可以独立使用这一段代码
- 相对路径:从当前模块开始,使用self 或者当前条目下是否可见这个代码块
6.2.1 super关键字
- 使用super关键字访问父级系统中的东西
- format super::
6.3 use关键字
- 使用use引入的时候,相当于这个模块直接定义在crate下面了
- 可以使用相对路径或者绝对路径进行引用
- 引入函数的时候,最好引用到函数的父级模块,不引用到函数。
- 使用struct enum的时候,引用到函数本身
- 引用同名的函数的时候,需要引用到函数的父模块
6.3.1 as关键字
可以使用as给函数起一个别名,这样方便同名函数的引用
6.3.2 pub use引用
- 重导出,可以将不可见的东西引用到外部,并且将其设置为可见
6.3.3 使用外部包
- cargo.toml里面添加依赖的包
- 在.rs文件中,利用use引用这个包
6.3.4 嵌套路径
使用嵌套路径来清理大量使用的use语句
-
format:路径相同的部分::{路径不同的地方};{}中不同的地方可以使用逗号进行分隔
-
一个引用是另一个引用的子引用可以使用self关键字
-
使用 通配符做全部的引用*
一般用于测试的时候
6.5 模块的拆分
- 可以使用mod的拆分进行模块的拆分
- 可以将模块里面的内容进行拆分,将模块拆成一部分一部分,但是仍然需要满足树形结构
chapter 7 常见集合数据类型
7.1 vector
7.1.1 vector的创建
- let v:Vec = Vec::new();
- let v =vec![1,2,3];
- vec!其实是一个宏对象
7.1.2 vector元素的更新
- v.push(1);
- 当vector离开作用域之后,里面的元素就会被清理掉
7.1.3 vector元素的读取
- 使用索引
- 使用get方法
- 两种方式超出范围的时候,希望程序崩溃使用索引,希望有报错信息,则使用get
- 不可以同时有可变借用和不可变借用
7.1.4 vector元素安排
- 连续存放的
- 存放在heap里面
7.1.5 vector的遍历
for i in %v{
println!("{}",i);
}
7.1.6 vector & enum
可以使用enum来初始化vector
7.2 String
- UTF-8编码
7.2.1 字符串是什么
- byte的集合
- 只提供了字符串切片存在
- 字符串字面值:存储在二进制文件中
- String和&str
7.2.2 String的创建
- let mut s = String::new() ;
- let date = “initial data”; let s =date.to_string();
- let s= String::from(”initial data”);
7.2.3 String的更新
let mut s =String::from(”foo”);
- s.push_str (”bar”);//不会抢夺s的所有权
- s.push(’l’);
- 字符串的拼接
-
- 方式
- format方式 (和println!不同)
-
let s1 =String::from("Hello");
let s2 =String::from("World");
let s3 = s1+&s2;//s1的所有权被抢夺走了,
//实际上调用的是add(self,s:&str);
let s4 = format!("{}-{}-{}",s1,s2,s3);
7.2.4 String类型
- String并没有实现对于idex的封装
- String.len();
- 里面的字符索引不一定可以对应到index
- 应为使用的可能是Unicode编码
- 计算机看待字符串应该是使用Unicode来看的
- 字节 →使用bytes()方法
- 标量值 → 使用chars()方法
- 字形簇(最接近我们人来看的)→需要调用第三方库
7.2.5 String的切片
- 切割的时候需要按照字符的边界来进行切割
- 否则,程序将会面临恐慌
7.3 HashMap
7.3.1 HashMap的定义
- HashMap<K,V>,K是键,V是value
- 通过K来寻找V
- HashMap不在prelude中
use std::collections::HashMap
fn main(){
let mut scores = HashMap::new();
scores.insert(String::from("Blue"),10);
scores.insert(String::from("red"),15);
}
7.3.2 使用Tuple来创建HashMap
use std::collections::HashMap
fn main(){
let teams = vec![String::from("Blue"),String::from("Yellow")];
let intial_scores = vec![10,50];
let scores:HashMap<_,_> =
teams.iter().zip(intial_scores.iter()).collect();
//collect()方法将这两个组合成一个tuple
}
7.3.3 所有权
- HashMap里面传的是引用的话,所有权不变,否则,所有权丢失
7.3.4 HashMap的遍历
let mut scores =HashMap::new();
scores.insert(String::from("Blue"),10);
scores.insert(String::from("Red"),50);
for (k,v) in &scores
//使用的是HashMap的引用,目的是因为后续还要使用HashMap
{
println!("{}:{}",k,v);
}
7.3.5 HashMap元素的更新
- 每个k只能对应一个v
- 替换现有的V
- 使用entry方法:检查指定的K是否对应一个V
// 检查存不存在
1. 存在可变引用
2. 不存在,就是可以插入
scores.entry(String::from("Hello world")).or_insert(50);
7.3.6 Hash函数
- 可以抵抗DoS攻击
- 可以切换其它Hash函数