软件系统开发定制【一起学Rust | 进阶篇 | Grid库】二维表数据结构——Grid

文章目录


前言

软件系统开发定制是个连续可增长的二维数据结构。这个 crate 软件系统开发定制的目的是提供一个比简单的Vec<Vec<T>>软件系统开发定制解决方案更快、软件系统开发定制使用更少的并且更容易软件系统开发定制使用的通用的数据结构。

Grid就像C软件系统开发定制语言风格的一样使用,软件系统开发定制拥有连续的存储内存。

注意Grid采用行优先的方式进行内存布局,因此使用grid.push_row()要比grid.push_col()快得多。


一、Grid安装和引入

Cargo.toml文件中引入

[dependencies]grid = { version = "*", default-features = false }
  • 1
  • 2

然后运行build命令,就会自动下载好Grid库,如果你是按照我前面的文章搭建的开发环境,那么只要你在Cargo.toml文件中引入了就会自动导入

cargo build
  • 1

二、使用

安装好以后,学习的时候先运行官方案例

1. 运行官方案例

首先是引入grid

use grid::*;
  • 1

创建一个二位表数组

let mut grid = grid![[1,2,3]                     [4,5,6]];
  • 1
  • 2

这行代码使用了一个宏grid!,他就等同于

let mut grid = Grid::from_vec(vec![1,2,3,4,5,6],3)
  • 1

现在来判断一下二者是否相同,如果真的二者相等,那么会正常编译通过

assert_eq!(grid, Grid::from_vec(vec![1,2,3,4,5,6],3));
  • 1

判断表(0,2)是否等于3

下表都是从0开始的,所以这个意思就是第1行,第三列

assert_eq!(grid.get(0,2), Some(&3));
  • 1

判断表(1,1)是否等于5

第二行 第二列

assert_eq!(grid[1][1], 5);
  • 1

判断表的大小是否等于(2,3)

2行 3列

assert_eq!(grid.size(), (2,3));
  • 1

插入一行数组

grid.push_row(vec![7,8,9]);
  • 1

判断新数组是否与grid![[1,2,3][4,5,6][7,8,9]]相等

assert_eq!(grid, grid![[1,2,3][4,5,6][7,8,9]])
  • 1

官方提供的案例完整代码如下

use grid::*;let mut grid = grid![[1,2,3]                     [4,5,6]];assert_eq!(grid, Grid::from_vec(vec![1,2,3,4,5,6],3));assert_eq!(grid.get(0,2), Some(&3));assert_eq!(grid[1][1], 5);assert_eq!(grid.size(), (2,3));grid.push_row(vec![7,8,9]);assert_eq!(grid, grid![[1,2,3][4,5,6][7,8,9]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2. Grid宏

grid宏是用来初始化一个grid二维数组的,它的用法在案例中就有体现

let grid = grid![[1, 2, 3][4, 5, 6][7, 8, 9]];
  • 1
  • 2
  • 3

3. new

用来构建一个,m行,n列的二维表,需要传入行数和列数,

let grid : Grid<u8> = Grid::new(2,2);
  • 1

4. init

使用指定的元素来初始化一个二维表,下面代码初始化了一个2行2列的二维表,初始化后,每个元素为5

let grid : Grid<u8> = Grid::init(2,2,5);
  • 1

5. from_vec

从给定向量创建二维表,

向量长度必须是列数的倍数

let grid = Grid::from_vec(vec![1,2,3,4,5,6], 3);
  • 1

如果不是列数的倍数就会报错,就像下面这样

let grid = Grid::from_vec(vec![1,2,3,4,5], 3);
  • 1

6. get

访问表中的某个元素。如果尝试访问超出表边界的元素,则返回 None。

7. get_mut

对表中某个元素的可变访问。如果尝试访问超出表边界的元素,则返回 None。

8. size

以两个元素元组的形式返回表的大小。第一个元素是行数,第二个元素是列数。

9. rows

返回表的行数。

10. cols

返回表的列数。

11. is_empty

如果表不包含任何元素,则返回 true。例如:

use grid::*;let grid : Grid<u8> = grid![];assert!(grid.is_empty());
  • 1
  • 2
  • 3

12. clear

清空二维表

13. iter

返回整个表的迭代器,从第一行和第一列开始。

use grid::*;let grid: Grid<u8> = grid![[1,2][3,4]];let mut iter = grid.iter();assert_eq!(iter.next(), Some(&1));assert_eq!(iter.next(), Some(&2));assert_eq!(iter.next(), Some(&3));assert_eq!(iter.next(), Some(&4));assert_eq!(iter.next(), None);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

14. iter_mut

返回允许修改每个值的整个表的可变迭代器。

use grid::*;let mut grid: Grid<u8> = grid![[1,2][3,4]];let mut iter = grid.iter_mut();let next = iter.next();assert_eq!(next, Some(&mut 1));*next.unwrap() = 10;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

15. iter_col

返回列上的迭代器。

use grid::*;let grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];let mut col_iter = grid.iter_col(1);assert_eq!(col_iter.next(), Some(&2));assert_eq!(col_iter.next(), Some(&4));assert_eq!(col_iter.next(), None);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果 col 索引超出范围,则会出现panic。

16. iter_col_mut

返回列上的可变迭代器。

use grid::*;let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];let mut col_iter = grid.iter_col_mut(1);let next = col_iter.next();assert_eq!(next, Some(&mut 2));*next.unwrap() = 10;assert_eq!(grid[0][1], 10);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果 col 索引超出范围,则会出现panic。

17. iter_row

返回一行的迭代器。

use grid::*;let grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];let mut col_iter = grid.iter_row(1);assert_eq!(col_iter.next(), Some(&3));assert_eq!(col_iter.next(), Some(&4));assert_eq!(col_iter.next(), Some(&5));assert_eq!(col_iter.next(), None);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果行索引超出范围,则会出现panic。

18. iter_row_mut

在一行上返回一个可变迭代器。

use grid::*;let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];let mut col_iter = grid.iter_row_mut(1);let next = col_iter.next();*next.unwrap() = 10;assert_eq!(grid[1][0], 10);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果行索引超出范围,则会出现panic。

19. push_row

在表中添加一个新行。

use grid::*;let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];let row = vec![6,7,8];grid.push_row(row);assert_eq!(grid.rows(), 3);assert_eq!(grid[2][0], 6);assert_eq!(grid[2][1], 7);assert_eq!(grid[2][2], 8);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

也可用于初始化一个空表:

use grid::*;let mut grid: Grid<u8> = grid![];let row = vec![1,2,3];grid.push_row(row);assert_eq!(grid.size(), (1, 3));
  • 1
  • 2
  • 3
  • 4
  • 5

20. push_col

在表中添加一个新列。

重要提示: 请注意Grid使用行优先内存布局。因此,该push_col() 操作需要相当多的内存转移,并且与操作相比push_row()会显著变慢。

use grid::*;let mut grid: Grid<u8> = grid![[1, 2, 3][3, 4, 5]];let col = vec![4,6];grid.push_col(col);assert_eq!(grid.cols(), 4);assert_eq!(grid[0][3], 4);assert_eq!(grid[1][3], 6);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

也可用于初始化一个空表:

use grid::*;let mut grid: Grid<u8> = grid![];let col = vec![1,2,3];grid.push_col(col);assert_eq!(grid.size(), (3, 1));
  • 1
  • 2
  • 3
  • 4
  • 5

如果表不为空,且col.len() != grid.rows()则会出现panic

21. pop_row

从表中删除最后一行并将其返回,如果为空则返回 None。

use grid::*;let mut grid = grid![[1,2,3][4,5,6]];assert_eq![grid.pop_row(), Some(vec![4,5,6])];assert_eq![grid.pop_row(), Some(vec![1,2,3])];assert_eq![grid.pop_row(), None];
  • 1
  • 2
  • 3
  • 4
  • 5

22. pop_col

从表中删除最后一列并返回它,如果为空则返回 None。

请注意,此操作比pop_row()的要慢得多,因为Grid的内存布局是行优先的,并且删除一列需要大量的移动操作。

use grid::*;let mut grid = grid![[1,2,3][4,5,6]];assert_eq![grid.pop_col(), Some(vec![3,6])];assert_eq![grid.pop_col(), Some(vec![2,5])];assert_eq![grid.pop_col(), Some(vec![1,4])];assert_eq![grid.pop_col(), None];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

23. insert_row

在索引处插入新行并在向下移动所有行。

use grid::*;let mut grid = grid![[1,2,3][4,5,6]];grid.insert_row(1, vec![7,8,9]);assert_eq!(grid[0], [1,2,3]);assert_eq!(grid[1], [7,8,9]);assert_eq!(grid[2], [4,5,6]);assert_eq!(grid.size(), (3,3))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

24. insert_col

在索引处插入一个新列。

注意列的插入比行的插入要慢得多。这是因为grid的内存布局。

use grid::*;let mut grid = grid![[1,2,3][4,5,6]];grid.insert_col(1, vec![9,9]);assert_eq!(grid[0], [1,9,2,3]);assert_eq!(grid[1], [4,9,5,6]);assert_eq!(grid.size(), (2,4))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

25. flatten

返回对表内部数据结构的引用。

grid使用行优先布局。在向量数据结构中,所有行都紧挨着放置。

use grid::*;let grid = grid![[1,2,3][4,5,6]];let flat = grid.flatten();assert_eq!(flat, &vec![1,2,3,4,5,6]);
  • 1
  • 2
  • 3
  • 4

26. into_vec

将 self 转换为没有克隆或分配的向量。

27. transpose

转置表,使列成为新表中的行。

28. fill

通过克隆用元素填充表的值。

use grid::*;let mut grid = grid![[1,2,3][4,5,6]];grid.fill(7);assert_eq!(grid[0], [7,7,7]);assert_eq!(grid[1], [7,7,7]);
  • 1
  • 2
  • 3
  • 4
  • 5

29. fill_with

用重复调用闭包返回的元素填充表。

use grid::*;let mut grid = grid![[1,2,3][4,5,6]];grid.fill_with(Default::default);assert_eq!(grid[0], [0,0,0]);assert_eq!(grid[1], [0,0,0]);
  • 1
  • 2
  • 3
  • 4
  • 5

总结

本期学习了中二维表的使用,包括

  • 二维表的创建
  • 增加行
  • 增加列
  • 填充
  • 插入
  • 弹出
  • 迭代

等相关操作。

本文你可以用来学习Rust的二维表,也可以作为你学习Rust二维表的一个查询手册,需要用到时,随时查询,提高你编程的效率。

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发