深入RUST標準庫內(nèi)核(四 Iterator)— Slice實現(xiàn)

本書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ù)。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容