本书github链接:inside-rust-std-library
前面章节参见:
深入RUST标准库内核(序言) - 简书 (jianshu.com)
深入RUST标准库内核(一 概述) - 简书 (jianshu.com)
深入RUST标准库内核(二 内存)—Layout/原生指针 - 简书 (jianshu.com)
深入RUST标准库内核(二 内存)—NonNull<T>/申请及释放 - 简书 (jianshu.com)
深入RUST标准库内核(二 内存)—mem模块/MaybeUninit<T> - 简书 (jianshu.com)
深入RUST标准库内核 (三 基础Trait) 编译器内置Trait - 简书 (jianshu.com)
深入RUST标准库内核(三 基础Trait)— Ops Trait - 简书 (jianshu.com)
深入RUST标准库内核(三 基本Trait)—Range - 简书 (jianshu.com)
深入RUST标准库内核(三 基础Trait)—Index Trait - 简书 (jianshu.com)
深入RUST标准库内核(四 Iterator 实现)— Range实现 - 简书 (jianshu.com)
slice的Iterator实现
首先定义了适合&[T]的Iter结构:
pub struct Iter<'a, T: 'a> {
//当前元素的指针
ptr: NonNull<T>,
//尾元素指针,用ptr == end以快速检测iterator是否为空
end: *const T,
//用来表示iterator与容器类型的生命周期关系
_marker: PhantomData<&'a T>,
}
//判断Iterator是否为空的宏
macro_rules! is_empty {
// 可以满足0字节元素的切片及非0字节元素的切片
($self: ident) => {
//Iter::ptr == Iter::end
$self.ptr.as_ptr() as *const T == $self.end
};
}
//取Iterator长度的宏
macro_rules! len {
($self: ident) => {{
let start = $self.ptr;
let size = size_from_ptr(start.as_ptr());
//判断元素是否为0字节
if size == 0 {
// 用end减start得到0字节元素的切片长度
($self.end as usize).wrapping_sub(start.as_ptr() as usize)
} else {
//非0字节,用内存字节数除以单元素长度
let diff = unsafe { unchecked_sub($self.end as usize, start.as_ptr() as usize) };
unsafe { exact_div(diff, size) }
}
}};
}
//用宏实现Iterator Trait
macro_rules! iterator {
(
struct $name:ident -> $ptr:ty,
$elem:ty,
$raw_mut:tt,
{$( $mut_:tt )?},
{$($extra:tt)*}
) => {
// 正向next函数辅助宏,实际的逻辑见post_inc_start函数
macro_rules! next_unchecked {
($self: ident) => {& $( $mut_ )? *$self.post_inc_start(1)}
}
// 反向的next函数
macro_rules! next_back_unchecked {
($self: ident) => {& $( $mut_ )? *$self.pre_dec_end(1)}
}
// 0元素next的移动
macro_rules! zst_shrink {
($self: ident, $n: ident) => {
//0元素数组因为不能移动指针,所以移动尾指针
$self.end = ($self.end as * $raw_mut u8).wrapping_offset(-$n) as * $raw_mut T;
}
}
//具体的方法实现
impl<'a, T> $name<'a, T> {
// 从Iterator获得切片.
fn make_slice(&self) -> &'a [T] {
// ptr::from_raw_parts,由内存首地址和切片长度创建切片指针,然后转换为引用
unsafe { from_raw_parts(self.ptr.as_ptr(), len!(self)) }
}
//实质的next
unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
if mem::size_of::<T>() == 0 {
//0字节元素偏移实现,调整end的值,ptr不变
zst_shrink!(self, offset);
self.ptr.as_ptr()
} else {
//非0字节元素,返回首地址,首地址然后后移正确的字节
let old = self.ptr.as_ptr();
self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().offset(offset)) };
old
}
}
// 从尾部做Iterator的实际实现函数
unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
if mem::size_of::<T>() == 0 {
//对于0字节元素,从头部及从尾部逻辑相同
zst_shrink!(self, offset);
self.ptr.as_ptr()
} else {
//尾部的end即偏移后的位置。
self.end = unsafe { self.end.offset(-offset) };
self.end
}
}
}
//Iterator的实现
impl<'a, T> Iterator for $name<'a, T> {
type Item = $elem;
#[inline]
fn next(&mut self) -> Option<$elem> {
unsafe {
//安全性确认
assume(!self.ptr.as_ptr().is_null());
if mem::size_of::<T>() != 0 {
assume(!self.end.is_null());
}
if is_empty!(self) {
//Iter为空的话,返回None
None
} else {
//实际调用post_inc_start(1)
Some(next_unchecked!(self))
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let exact = len!(self);
(exact, Some(exact))
}
fn count(self) -> usize {
len!(self)
}
fn nth(&mut self, n: usize) -> Option<$elem> {
//如果n大于Iter的长度,清空
if n >= len!(self) {
if mem::size_of::<T>() == 0 {
self.end = self.ptr.as_ptr();
} else {
unsafe {
self.ptr = NonNull::new_unchecked(self.end as *mut T);
}
}
return None;
}
// 否则,失效前n-1个元素,然后做neet
unsafe {
self.post_inc_start(n as isize);
Some(next_unchecked!(self))
}
}
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
//取长度与n中的小值
let advance = cmp::min(len!(self), n);
//失效advance-1个值
unsafe { self.post_inc_start(advance as isize) };
//返回
if advance == n { Ok(()) } else { Err(advance) }
}
//从尾部Iterator
fn last(mut self) -> Option<$elem> {
//实质调用post_dec_end(1)
self.next_back()
}
//其他,略
...
...
}
}
}
impl<'a, T> Iter<'a, T> {
pub(super) fn new(slice: &'a [T]) -> Self {
let ptr = slice.as_ptr();
// SAFETY: Similar to `IterMut::new`.
unsafe {
assume(!ptr.is_null());
let end = if mem::size_of::<T>() == 0 {
//如果切片元素是0字节类型,end 为 首地址加 切片长度字节。即每个元素一个字节
(ptr as *const u8).wrapping_add(slice.len()) as *const T
} else {
//end为slice.len() * mem::<T>::size_of()
ptr.add(slice.len())
};
//PhantomData会做类型推断,带入T的类型和生命周期
Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData }
}
}
...
...
}
//宏声明
iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, {}}
基本上,一个容器类的Iterator的实现基本上是必须要用ptr及mem模块的函数。