深入RUST标准库内核(三 基本Trait)—Range

本书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)

Range 运算符代码分析

Range是符号 .. , start..end , start.. , ..end , ..=end,start..=end 形式

Range相关的边界结构Bound

源代码:

pub enum Bound<T> {
    /// An inclusive bound.
    /// 边界包括
    Included(T),
    /// An exclusive bound.
    /// 边界不包括
    Excluded(T),
    /// An infinite endpoint. Indicates that there is no bound in this direction.
    /// 边界不存在
    Unbounded,
}

Include边界的值包含,Exclued边界的值不包含,Unbounded边界值不存在

RangeFull

..的数据结构。

Range<Idx>

start.. end的数据结构

RangeFrom<Idx>

start..的数据结构

RangeTo<Idx>

.. end的数据结构

RangeInclusive<Idx>

start..=end的数据结构

RangeToInclusive<Idx>

..=end的数据结构

RangeBounds<T: ?Sized>

所有Range统一实现的Trait。

pub trait RangeBounds<T: ?Sized> {
    /// 获取范围的起始值
    ///
    /// 例子
    /// # fn main() {
    /// use std::ops::Bound::*;
    /// use std::ops::RangeBounds;
    ///
    /// assert_eq!((..10).start_bound(), Unbounded);
    /// assert_eq!((3..10).start_bound(), Included(&3));
    /// # }
    /// ```
    fn start_bound(&self) -> Bound<&T>;

    /// 获取范围的终止值.
    /// 例子
    /// # fn main() {
    /// use std::ops::Bound::*;
    /// use std::ops::RangeBounds;
    ///
    /// assert_eq!((3..).end_bound(), Unbounded);
    /// assert_eq!((3..10).end_bound(), Excluded(&10));
    /// # }
    /// ```
    fn end_bound(&self) -> Bound<&T>;

    /// 范围是否包括某个值.
    /// 例子
    /// assert!( (3..5).contains(&4));
    /// assert!(!(3..5).contains(&2));
    ///
    /// assert!( (0.0..1.0).contains(&0.5));
    /// assert!(!(0.0..1.0).contains(&f32::NAN));
    /// assert!(!(0.0..f32::NAN).contains(&0.5));
    /// assert!(!(f32::NAN..1.0).contains(&0.5));
    fn contains<U>(&self, item: &U) -> bool
    where
        T: PartialOrd<U>,
        U: ?Sized + PartialOrd<T>,
    {
        (match self.start_bound() {
            Included(start) => start <= item,
            Excluded(start) => start < item,
            Unbounded => true,
        }) && (match self.end_bound() {
            Included(end) => item <= end,
            Excluded(end) => item < end,
            Unbounded => true,
        })
    }
}

RangeBounds针对RangeFull,RangeTo, RangeInclusive, RangeToInclusive, RangeFrom, Range结构都进行了实现。同时针对(Bound<T>, Bound<T>)的元组做了实现。

Range的独立性

Range操作符多用于与Index运算符结合或与Iterator Trait结合使用。在后继的Index运算符和Iterator中会研究Range是如何与他们结合的。

小结

基于泛型的Range类型提供了非常好的语法手段,只要某类型支持排序,那就可以定义一个在此类型基础上实现的Range类型。再结合Index和Iterator, 将高效的实现极具冲击力的代码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容