本書github鏈接:inside-rust-std-library
前面章節(jié)參見:
深入RUST標準庫內(nèi)核(序言) - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(一 概述) - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(二 內(nèi)存)—Layout/原生指針 - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(二 內(nèi)存)—NonNull<T>/申請及釋放 - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(二 內(nèi)存)—mem模塊/MaybeUninit<T> - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核 (三 基礎Trait) 編譯器內(nèi)置Trait - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(三 基礎Trait)— Ops Trait - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(三 基本Trait)—Range - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(三 基礎Trait)—Index Trait - 簡書 (jianshu.com)
深入RUST標準庫內(nèi)核(四 Iterator 實現(xiàn))— Range實現(xiàn) - 簡書 (jianshu.com)
slice的Iterator實現(xiàn)
首先定義了適合&[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字節(jié)元素的切片及非0字節(jié)元素的切片
($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字節(jié)
if size == 0 {
// 用end減start得到0字節(jié)元素的切片長度
($self.end as usize).wrapping_sub(start.as_ptr() as usize)
} else {
//非0字節(jié),用內(nèi)存字節(jié)數(shù)除以單元素長度
let diff = unsafe { unchecked_sub($self.end as usize, start.as_ptr() as usize) };
unsafe { exact_div(diff, size) }
}
}};
}
//用宏實現(xiàn)Iterator Trait
macro_rules! iterator {
(
struct $name:ident -> $ptr:ty,
$elem:ty,
$raw_mut:tt,
{$( $mut_:tt )?},
{$($extra:tt)*}
) => {
// 正向next函數(shù)輔助宏,實際的邏輯見post_inc_start函數(shù)
macro_rules! next_unchecked {
($self: ident) => {& $( $mut_ )? *$self.post_inc_start(1)}
}
// 反向的next函數(shù)
macro_rules! next_back_unchecked {
($self: ident) => {& $( $mut_ )? *$self.pre_dec_end(1)}
}
// 0元素next的移動
macro_rules! zst_shrink {
($self: ident, $n: ident) => {
//0元素數(shù)組因為不能移動指針,所以移動尾指針
$self.end = ($self.end as * $raw_mut u8).wrapping_offset(-$n) as * $raw_mut T;
}
}
//具體的方法實現(xiàn)
impl<'a, T> $name<'a, T> {
// 從Iterator獲得切片.
fn make_slice(&self) -> &'a [T] {
// ptr::from_raw_parts,由內(nèi)存首地址和切片長度創(chuàng)建切片指針,然后轉換為引用
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字節(jié)元素偏移實現(xiàn),調(diào)整end的值,ptr不變
zst_shrink!(self, offset);
self.ptr.as_ptr()
} else {
//非0字節(jié)元素,返回首地址,首地址然后后移正確的字節(jié)
let old = self.ptr.as_ptr();
self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().offset(offset)) };
old
}
}
// 從尾部做Iterator的實際實現(xiàn)函數(shù)
unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
if mem::size_of::<T>() == 0 {
//對于0字節(jié)元素,從頭部及從尾部邏輯相同
zst_shrink!(self, offset);
self.ptr.as_ptr()
} else {
//尾部的end即偏移后的位置。
self.end = unsafe { self.end.offset(-offset) };
self.end
}
}
}
//Iterator的實現(xiàn)
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 {
//實際調(diào)用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> {
//實質調(diào)用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字節(jié)類型,end 為 首地址加 切片長度字節(jié)。即每個元素一個字節(jié)
(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的實現(xiàn)基本上是必須要用ptr及mem模塊的函數(shù)。