rust复合类型-数组

本文详细介绍了Rust中数组的声明、初始化、元素访问、长度获取、循环遍历、可变数组、切片、作为函数参数以及各种操作如排序、映射、转换等。
摘要由CSDN通过智能技术生成

一、概要

数组(arry)

定义:数组是一组拥有相同类型T的对象的集合,在内存中是连续存储的。

数组的特征:

  • 数组声明分配顺序内存块。
  • 长度固定。
  • 数组是静态的。这意味着数组一旦初始化就无法调整大小。
  • 每个内存块代表一个数组元素。
  • 数组元素由一个唯一的整数标识,称为元素的下标/索引。注意:数组下边从0开始。
  • 填充数组元素称为数组初始化。
  • 数组元素值可以更新或修改,但不能删除。
  • 数组是存储在栈上。因此访问速度更快。

声明和初始化

rust提供3种语法

1.最基本的语法,指定每一个元素的初始值

let variable_name:[dataType; size] = [ value1, value2, value3];

例如

let arr:[i32; 4] = [10, 20, 30, 40];

2.省略数组类型的语法

let variable_name = [value1, value2, value3];

例如

let arr = [ 10, 20, 30, 40];

3.指定默认初始值的语法,这种语法称为默认值初始化。

如果不想为每一个元素指定初始值,则可以为所有元素指定一个默认的初始值。

let variable_name:[dataType;size] = [default_value_for_elements; size];

例如 :为每一个元素指定初始值为-1

let arr:[i32; 4] = [-1; 4];

访问数组元素

fn main(){
    let arr = [9, 8, 7, 6, 5]
    //let arr:[i32; 4] = [9, 8, 7, 6, 5];
    
    let first = arr[0]; //获取arr数组的第一个元素
    let second = arry[1]; //获取arr数组的第二个元素
}

数组长度 len()

fn main(){
    let arr:[i32; 4] = [-1; 4];

    println!("arry size is :{}", arr.len());
}
//输出结果
arry size is :4

循环遍历数组for in

fn main(){
    let arr:[i32; 4] = [10, 20, 30, 40];

    for i in 0..4 {
        println!("i is : {}, value is : {}", i, arr[i]);
}
//输出结果
i is : 0, value is : 10
i is : 1, value is : 20
i is : 2, value is : 30
i is : 3, value is : 40

迭代数组 iter()

fn main(){
    let arr:[i32; 4] = [10, 20, 30, 40];
    for val in arr.iter(){
        println!("value is : {}", val);
    }
}
//输出结果
value is : 10
value is : 20
value is : 30
value is : 40

可变数组

fn main(){
    let mut arr:[10, 20, 30, 40];
    arr[1] = 0;
    println!("{:?}", arr);
}
//输出结果
[10, 0, 30, 40]

数组切片

fn main(){
    let a: [i32; 5] = [1, 2, 3, 4, 5];
    let slice: &[i32] = &a[1..3];
    assert_eq!(slice, &[2, 3]);
}

数组作为函数参数

数组可以作为函数的参数,传递方式有传值传递和引用传递两种方式。

传值传递就是传递数组的一个副本给函数做参数,函数对副本的任何修改都不会影响到原来的数组。

fn main(){
    let arr = [10, 20, 30]
    update(arr);

    println!("Inside main {:?});
}

fn update(mut arr:[i32; 3]){
    for i in 0..3 {
        arr[i] = 0;
    }
    
    println!("Inside update {:?}", arr);
}

//输出结果
Inside update [0, 0, 0]
Inside main [10, 20, 30]

引用传递就是传递数组在内存上的位置给函数左参数,因此函数对数组的任何修改都会影响到原来的数组。

fn main(){
    let mut arr = [10, 20, 30];
    update(&mut arr);
    
    println!("Inside main {:?}", arr);
}

fn update(arr: &mut [i32; 3]){
    for i in 0..3 {
        arr[i] = 0;
    }

    println!("Inside update {:?}", arr);
}

//输出结果
Inside update [0, 0, 0]
Inside main [0, 0, 0]

属性、方法和函数

len(): 返回数组的长度。

let arr = [1, 2, 3, 4, 5];
assert_eq!(arr.len(), 5);

is_empty(): 判断数组是否为空,如果长度为0返回true,否则返回false。

let arr: [i32; 0] = [];
assert_eq!(arr.is_empty(), ture);

first():返回数组的第一个元素的引用,如果数组为空返回None。

let arr = [1, 2, 3];
assert_eq!(arr.first(), Some(&1));

first_mut(): 返回数组的第一个元素的可变引用,如果数组为空,则返回None。

let mut arr = [1, 2, 3];
if let Some(n) = arr.first_mut(){
    *n *=2;
}
assert_eq!(arr, [2,2,3]);

last():返回数组的最后一个元素的引用,如果数组为空返回None。

let arr = [1, 2, 3];
assert_eq!(arr.last(), Some(&3));

last_mut():返回数组的最后一个元素的可变引用,如果数组为空,则返回None。

let mut arr = [1, 2, 3];
if let Some(n) = arr.last_mut(){
    *n *=2;
}
assert_eq!(arr, [1, 2, 6]);

get():通过索引获取数组元素的引用,如果索引越界返回None。

let mut arr = [1, 2, 3];
assert_eq!(arr.get(1), Some(&2));
assert_eq!(arr.get(3), None);

get_mut(): 返回给定索引处的元素的可变引用,如果索引越界,则返回None。

let mut arr = [1, 2, 3];
if let Some(n) = arr.get_mut(1){
    *n *=2;
}
assert_eq!(arr, [1, 4, 3]);

contains(): 判断数组是否包含指定的元素。

let arr = [1, 2, 3];
assert_eq!(arr.contcains(&3));
assert|_eq!(arr.contcains(&6));

starts_with(): 判断数组是否以指定的前缀开头。

let arr = [1, 2, 3, 4, 5];
assert_eq!(arr.starts_with(&[1, 2, 3]));
assert_eq!(arr.starts_with(&[2,3, 4]));
let arr = [1, 2, 3, 4, 5];
assert_eq!(arr.ends_with(&[4, 5]));
assert_eq!(arr.ends_with(&[3, 4, 5]));

repeat():创建重复指定次数的数组。

let arr = [1, 2];
let repeated: Vec<i32> = arr.repeat(3);
assert_eq!(repeat, [1, 2, 1, 2, 1, 2]);

fill():将数组中所有元素替换为给定的值。

let mut arr = [1, 2, 3];
arr.fill(0);
assert_eq!(arr, [3, 2, 1});

swap(): 交换数组中两个元素的位置。

let mut arr = [1, 2, 3];
arr.swap(0, 2);
assert_eq!(arr, [3, 2, 1]);

binary_search_by_key(): 在有序数组中搜索指定键的元素,在找到元素时返回其索引,否则返回应该插入元素的位置的索引,维持数组的有序状态。

let arr = [(1, "one"), (3, "three"), (5, "five"), (7, "seven"), (9, "nine")];
let result = arr.binary_search_by_key(&7, |&key, _) key);
assert_eq!(result, Ok(3));

let arr = [(1, "apple"), (3, "banana"), (5, "cherry"), (7, "pear"), (9, "watermelon")];
assert_eq!(arr.binary_search_by_key(&5, |&(k, _)| k), Ok(2));
assert_eq!(arr.binary_search_by_key(&4, |&(k, _)| k), Err(2));
assert_eq!(arr.binary_search_by_key(&10, |&(k, _)| k), Err(5));

iter():返回数组的迭代器,可用于遍历数组中的元素。

let arr = [1, 2, 3];
for i in arr.iter(){
    println!("{}", i);
}
//输出结果
1 2 3

iter_mut():返回一个可变的迭代器,可用于遍历和修改数组中的元素。

let mut arr = [1, 2, 3];
let s =arr.as_mut();
s[1] = 4;
assert_eq!(arr, [1, 4, 3]);

into_iter():返回一个消耗性迭代器,可对数组进行所有权转移,在迭代过程中释放数组的所有权。

let arr = [1, 2, 3];
let v:Vec<i32> = arr.into_iter().map(|x| x*2).collect();
assert_eq!(v, vec![2, 4, 6];

as_mut(): 返回一个可变引用的切片,可以修改数组中的元素。

let mut arr = [1, 2, 3];
let s = arr.as_mut();
s[1] = 4;
assert_eq!(1, 4, 3]);

as_ptr():返回数组的指针。

let arr = [ 1, 2, 3];
let p = arr.ptr();
unsafe{
    println!("{}", *p.offset(1));
}
//输出结果
2

split():根据条件分割数组,返回一个可迭代的切片集合。

let arr = [1, 2, 3, 4, 5];
let mut splits = arr.split(|x| x%2 == 0);
let s1 = splits.next().unwrap();
let s2 = splits.next().unwrap();
let s3 = splits.next().unwrap();
assert_eq!(s1, [1]);
assert_eq!(s2, [3]);
assert_eq!(s3, [5]);

split_at():从数组中分割出两个切片,将数组分成两部分。

let arr = [1, 2, 3, 4, 5];
let (left, right) = arr.split_at(2);
assert_eq!(left, [1, 2]);
assert_eq!(right, [3, 4, 5]);

split_first():返回数组中的第一个元素。

let arr = [1, 2, 3, 4, 5];
let (first, rest) = arr.split_first().unwrap();
assert_eq!(*first, 1);
assert_eq!(rest, &[2, 3, 4, 5]);

split_first_mut():返回一个数组的第一个可变引用。

let mut arr = [1, 2, 3, 4, 5];
let (first, rest) = arr.split_mut().unwrap();
*first = 0;
assert_eq!(arr, [0, 2, 3, 4, 5]);

chunks():返回以恶可迭代的切片集合,每个切片包含指定大小的元素。

let arr = [1, 2, 3, 4, 5];
let mut chunks = arr.chunks(2);
let c1 = chunks.next().unwrap();
let c2 = chunks.next().unwrap();
let c3 = chunks.next().unwrap();
assert_eq!(c1, [1, 2]);
assert_eq!(c2, [3, 4]);
assert_eq!(c3, [5]);

chunks_mut():返回一个可变的可迭代切片集合,每个切片包含指定大小的元素。

let arr = [1, 2, 3, 4, 5];
for chunk in arr.chunks_mut(2){
    chunk[0] +=1;
}
assert_eq!(arr, [2, 2, 4, 4, 5]);

chunks_exact():返回可迭代的切片集合,每个切片包含指定大小的元素,最后不足一个切片的部分将被忽略。

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
let mut chunks = arr.chunks_exact(3);
let c1 = chunks.next().unwrap();
let c2 = chunks.next().unwrap();
let c3 = chunks.next().unwrap();
let c4 = chunks.next().unwrap();
assert_eq!(c1, [1, 2, 3]);
assert_eq!(c2, [4, 5, 6]);
assert_eq!(c3, [7, 8, 9]);
assert_eq!(c4, [10, 11]);

chunks_exact_mut(): 返回可变的可迭代的切片集合,每个切片包含指定大小的元素,最后不足一个切片的部分将被忽略。

let mut arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for chunk in arr.chunks_exact_mut(3){
    chunk[0] += 1;
}
assert_eq!(arr, [2, 2, 4, 5, 6, 8, 7, 8, 9]);

join():将数组中的元素按指定的分隔符连接成一个字符串。

let arr = [1, 2, 3];
let joined = arr.join(", ");
assert_eq!(joined, "1, 2, 3");

let arr = ["one", "two", "three"];
let s = arr.join(", ");
assert_eq!(arr, "one, two, three");

reverse():反转数组中元素的顺序。

let mut arr = [1, 2, 3, 4, 5];
arr.reverse();
assert_eq!(s, [5, 4, 3, 2, 1]);

sort():对数组进行排序,按元素大小升序排序。

let arr = [3, 1, 4, 2, 5];
arr.sort();
assert_eq!(arr, [1, 2, 3, 4, 5]);

sort_by():对数组进行排序,按指定的比较函数进行排序。

let mut arr = ["apple", "banana", "cherry", "pear", "watermelon"];
arr.sort_by(|a, b| a.len().cmp(&b.len()));
assert_eq!(arr, ["pear", "apple", "banana", "cherry", "watermelon"]);

sort_by_key():对数组进行排序,按指定的键进行排序。

let mut arr = [(3, "banana"), (1, "apple"), (5, "cherry"), (7, "pear"), (9, "watermelon")];
arr.sort_by_key(|&k, _)| k);
assert_eq!(arr, [(1,"apple", (3, "banana"), (5, "cherry"), (7, "pear"), (9, "watermelon")];

map():将数组中的每个元素应用给定的函数,并返回一个新的数组。

let arr = [1, 2, 3];
let arr2 = arr.map(|n| n*2);
assert_eq!(arr2, [2, 4, 6]);

rotate_left():循环移动数组元素,将第一个元素移动到数组末尾。

let mut arr = [1, 2, 3, 4, 5];
arr.rotate_left(2);
assert_eq!(arr, [3, 4, 5, 1, 2]);

rotate_right():循环移动数组元素,将最后一个元素移动到数组开头。

let mut arr = [1, 2, 3, 4, 5];
arr.rotate_right(2);
assert_eq!(arr, [ 4, 5, 1, 2, 3]);

to_string():将数组转换为字符串类型。

let arr = [1, 2, 3];
let s = arr.to_string();
assert_eq!(s, "[1, 2, 3]");

to_vec():将数组转换为向量类型(Vec)。

let arr = [1, 2, 3];
let vec = arr.to_vec();
assert_eq!(s, vec![1, 2, 3]);

to_slice():将数组转换为切片类型,并且可以指定开始和结束位置。

let arr = [1, 2, 3, 4, 5];
let slice = arr.to_slice();
assert_eq!(slice, &[1, 2, 3, 4, 5]);

into_iter():返回一个将数组转换为迭代器的方法。

let arr = [1, 2, 3];
for n in arr.into_iter(){
    println!("{}", n);
}

try_fold():对数组中的每个元素应用给定的函数,并且在每次应用后返回一个Result类型,最后将所有Ok类型的值聚合在一起。

let arr = ["1", "2", "three", "4", "five"];
let result = arr.try_fold(0, |acc, n|{
    if let Ok(num) = n.parse::<i32>(){
        Ok(acc + num)
        } else{
            Err(())
        }
});
assert_eq!(result, Err(()));

try_for_each():对数组中的每个元素应用给定的函数,并且在 每次应用后返回一个Result类型,如果所有应用都成功,则返回Ok(())。

let arr = ["1", "2", "3"];
let result = arr.try_for_each(|n| {
    if n.parse::<i32>().is_ok(){
        Ok(())
    } else {
        Err(())
    }
});
assert_eq!(result, Ok(()));

permutations():返回一个可迭代的集合,包含数组中所有元素的所有可能的排列组合。

let arr = [1, 2, 3];
let mut permutations = arr.permutations();
assert_eq!(permutations.next(), Some([1, 2, 3]));
assert_eq!(permutations.next(), Some([1, 3, 2]));
assert_eq!(permutations.next(), Some([2, 1, 3]));
assert_eq!(permutations.next(), Some([2, 3, 1]));
assert_eq!(permutations.next(), Some([3, 1, 2]));
assert_eq!(permutations.next(), Some([3, 2, 1]));

zip():将两个数组压缩成一个元组的集合。

let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let result:Vec<_> = arr1.iter().zip(arr2.iter()).collect();
assert_eq!(result, [(1, 4), (2, 5), (3, 6)]);

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值