Std
Rust的标准库
Rust的标准库分为几个部分 它们是自底向上的依赖关系
原始数据类型: 基本数据类型 array, f32 ,i32 ...
core: Rust最基本的环境 不依赖系统 文件系统 内存分配,也就是no_std环境. 用于嵌入式 内核开发
alloc: 堆分配支持 适用于有堆但无std的环境
std: 完整的标准库
proc_macro: 标准库的宏库
test: 标准库的测试宏与框架
core
Rust核心库是Rust标准库的无依赖基础 它没有链接到上游库 没有系统库 也没有 libc
primitive types
原始数据类型 不过多介绍
数字类型
方法
trailing_zeros: 返回尾随的0即从右往左的第一个1右边有几个0.leading_zeros: 返回前导0即从左往右的第一个1右边有几个0.
bool
then(self, f: F): 如果是true 则返回f 否则Nonethen_some(self, t: T): 如果是true 则返回T 否则None
pointer
裸指针 *const T 与 *mut T.
注意, *ptr = data操作会在原来地址上的值上调用drop() 所以如果原来的内存没有初始化的化 这是个未定义行为. 这个时候我们可以使用core::ptr::write() 这个方法不会调用原来地址的drop()
创建裸指针的方法:
对于栈上的 可以从 引用转换而来.
let a: i32 = 10;
let ptr: *const i32 = &a;
对于堆上的 可以 解引用
Box. 但是注意 这并不会获得Box在堆上的所有权, Box的所有权仍然会在超出作用域drop, 这个时候用ptr会未定义行为.
let a: Box<i32> = Box::new(10);
let ptr: *const i32 = &*a;
消费box
box的into_raw()函数会消费自己 并返回裸指针. 但是注意: 那个数据还在堆上 我们需要手动管理它的所有权.
let a: Box<i32> = Box::new(1);
let a_ptr: *mut i32 = Box::into_raw(a);
unsafe {
drop(Box::from_raw(a));
}
iter
迭代器
迭代器是指实现了Iterator trait的类型
Iterator
迭代器的Trait
pub trait Iterator {
type Item;
}
其中Item是迭代器吐出的元素的类型
必须方法:
next 推动迭代器 并返回下一个值. 其中,迭代完成返回
Option::None.
不同的实现可能会在返回None后 继续调用next 会返回Some
fn next(&mut self) -> Option<Self::Item>
fold
累加器
fn fold<B,F>(self,init: B,f: F) -> B
where
Self: Sized,
F: FnMut(B,Self::Item) -> B,
init为初始值 f为累加的闭包
举例: 0..101的和
let sum = (0..101).into_iter().fold(0,|acc,x| acc + x);
filter
过滤器 , 将满足条件的元素返回成一个迭代器.
fn filter<P>(self,predicate: P) -> Filter<Self,P>
where
self: Sized,
P: FnMut(&self::Item) -> bool,
举例: 0..101的偶数的和
let sum = (0..101).into_iter().filter(|i| i % 2 == 0).fold(0,|acc,x| acc + x);
map
给迭代器的每个元素应用一个操作 然后返回作用后的迭代器.
fn map<B,F>(self, f:F) -> Map<Self,F>
where
Self: Sized,
F: FnMut(Self::Item) -> B
举例: 将(0..101)的每个数对9取余.
(0..101).into_iter().map(|i| i % 9)
ops
可重载运算符
Fn/FnMut/FnOnce
闭包实现的Trait
Fn: 接收
&selfFn的实例可以在不改变状态的情况下重复调用。
pub trait Fn<Args: Tuple>: FnMut<Args> {
// Required method
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}
FnOnce: 接收
self调用会消耗自身 只能调用一次
pub trait FnOnce<Args: Tuple> {
type Output;
// Required method
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
FnMut: 接收
&mut self可以在改变状态的情况下重复调用
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
// Required method
extern "rust-call" fn call_mut(
&mut self,
args: Args
) -> Self::Output;
}
`
sync
线程同步原语
atomic
原子类型 提供线程之间的原始共享内存通信
Ordering
原子类型的内存排序严格程度
pub enum Ordering {
Relaxed,
Release,
Acquire,
AcqRel,
SeqCst,
}
Relaxed: 没有排序约束 只有原子操作
即:
对同一个原子变量 所有线程观察到的值的变化顺序一致. 若变量从0->1->2 所有线程看到的都是0->1->2
指令本身具有原子性 在
fetch_add之类的指令执行时 不会出现执行一半的情况
Release/Acquire: 这对组合建立前序与后序的关系
Acquire保证此操作之后的读取与写入不会被排到此操作前
Release保证此操作之前的读取与写入不会被排到此操作后
AcqRel: 等于Relase+AcquireSeqCst: 最严格的约束 在AcqRel的基础上要求 所有线程看到的SeqCst的操作顺序必须一致
cmp
比较模块
Ordering
两个值比较的结果
then(self, other: Ordering) -> Ordering: 链接两个排序.若self不是Equal则返回self. 否则返回other
ptr
裸指针
NonNull
非0且协变的*mut T.
由于NonNull是covariant的, 所以如果我们自己抽象的类型需要invariant 那么我们需要PhantomData调整variance.
方法
dangling(): 创建悬垂指针new_unchecked(ptr: *mut T) -> Self: 从*mut T创建NonNull<T>, 这里假定ptr一定非空.new(ptr: *mut T) -> Option<Self>: 与new_unchecked的区别在于 会先检查是否是空as_ptr(self) -> *mut T: 获取底层*mut指针
std
rust的全功能标准库. 包括了 Vec<T>, 操作系统I/O, 多线程等
boxed
在rust里 ,Box<T>的使命类似于C的malloc,free 即在堆上分配与管理对象.
而Box<T>具有堆上对象的所有权. 它是一个 智能指针.
collections
数据结构.
LinkedList
双向链表
pub struct LinkedList<
T,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
head: Option<NonNull<Node<T>>>,
tail: Option<NonNull<Node<T>>>,
len: usize,
alloc: A,
marker: PhantomData<Box<Node<T>, A>>,
}
struct Node<T> {
next: Option<NonNull<Node<T>>>,
prev: Option<NonNull<Node<T>>>,
element: T,
}
new(): 创建空的链表append(&mut self,other: &mut LinkedList<T,Global>): 将另一个链表other插入到self的后面push_back(&mut self,elt: T): 将元素追加到尾部push_front(&mut self,elt: T): 将元素追加到前面pop_front(&mut self,elt: T): 将最前面元素弹出pop_back(&mut self,elt: T): 将最后面元素弹出