阅读 161

关于rust的索引

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

区间Range

Rust中的range代表一个“区间”:

fn main(){
    let r = 1..10;
    for _i in i{
        //...
    }
}
复制代码

需要注意的是,在这个语法中,前面是开区间,后面是闭区间。这个语法实际上生产的是一个std::ops::Range<_>,这个类在标准库定义如下:

pub struct Range<Idx>{
    pub start: Idx;
    pub end: Idx;
}
复制代码

这个结构实现了Iteratortrait,因此可以应用到循环语句中。 在Rust中还有其他几种Range

  • std::ops::RangeFrom代表了只有开始,没有结束的范围。含义为:[start,...]

与此类似的还有RangeToRangeFull。具体可以查看rust文档。 使用上述的内置函数,我们可以灵活的对数组这种实现了iterator的类型进行循环,遍历。

    fn main(){
        let arr = [1,2,3,4,5];
        for i in &arr[..]{
            println!("{:?}",i)
        }
    }
    // 1 2 3 4 5
复制代码

边界检查

当我们在对数组进行拿值,或者遍历的时候,如果取到了一个不在数组范围内的值,这在rust中则会如之前文章讲的,发出一个panic错误,使程序退出,这代表了rust对程序运行安全的保护。其次在rust中如果我们要获取一个类型对象的索引,就需要该类型实现std::ops::Index trait,而如果同时获得可以对该值操作的权限,则要实现std::ops::IndexMuttrait。

为了防止这类错误,如果我们不确定我们的读取操作是否合法,应该使用rust提供的get()方法来获取索引的值,该方法会返回一个Result<T>类型的值:

let arr = [1,2,3];
println!("{:?}",arr.get(0));
println!("{:?}",arr.get(10));
//Some(1)
//None
复制代码

虽然Rust宣扬的是无Gc的内存安全,但对于数组越界这类问题导致的panic是否意味着Rust还不够安全呢,rust不鼓励大量的使用索引操作,每一次索引操作都会进行一次“边界检查”,这一点相对于C++运行效率就会变低,因为C++并不会执行这一操作,这对应了rust中的get_unchecked()操作。Rust中,我们应该尽量使用迭代器操作来获取我们想得到的值。

use std::iter::Iterator;
let arr = [1,2,3,4,5];
for (index,value) in arr.iter().enumerate(){
    println!("{:?}",index,value);
}
let i = v.iter().filter(|&x| *x*2==4)
println1("{:?}",i);
复制代码

这样,通过Iterator方法提高了程序运行的效率,也减少了我们程序出现错误的概率,是一个良好的开发习惯。

文章分类
后端
文章标签