3个版本
0.1.5 | 2021年6月30日 |
---|---|
0.1.4 |
|
0.1.3 | 2021年6月27日 |
0.1.2 |
|
0.1.0 | 2021年6月26日 |
#2066 在 数据结构
每月26次下载
在 simple_getopt 中使用
2MB
438 代码行
包含 (rust库,82KB) target/release/libarraylist.rlib,(rust库,82KB) libarraylist-27ddee64e3a271ff.rlib
arraylist
名称
arraylist
-- 在Rust向量实现之上构建的直观的Rust向量包装器。类似于Java Arraylist,也可以像Python列表函数和JavaScript数组一样使用。
安装
在 Cargo.toml 文件中
[dependancies]
arraylist = {git = "https://github.com/2teez/arraylist"}
OR
[dependancies]
arraylist = "0.1.3"
在 main.rs 文件中
使用方法
#[macro_use]
extern crate arraylist;
use arraylist::arl::ArrayList;
描述
arraylist
- 是基于Rust标准向量实现构建的rust包装器。它使得使用向量作为列表或在其他语言(如Java、JavaScript等)中的可增长数组时更加直观,无需与Rust借用检查器“战斗”;这是在Rust中编码时始终存在的、固执但伟大的朋友。
arraylist
不是在Rust中重写的 vec
,而是一个包装器,它提供了安全、更简单且可能的接口,同时使用了Rust语言提供的“内部可变性”。
使用 crate arraylist
可以使您能够处理不可变值、对象等,同时无需在代码的每个地方都使用“mut”关键字,即可进行多次更改。尽管如此,您可能仍然需要在某些情况下使用它。但您大部分时间都在处理不可变值。
arraylist crate 提供的函数与 Java ArrayList 方法非常相似。即使您以前没有使用过 Java,它也会感觉直观,并隐藏了 rust-lang 中的一些“头疼”的工作。
示例
以下代码仅使用 rust 中的 vec 无法实现
let vec = vec![1, 2, 3, 4, 5];
vec.push(6); // cannot borrow as mutable
使用 arraylist,可以这样工作,使用不可变变量
let arr = arraylist![1, 2, 3, 4];
arr.push(5);
arr.push(6);
// print out your arraylist like so:
arr.print(); // [1, 2, 3, 4, 5, 6]
然而,要在 vec
中获得相同的结果,您必须使变量可变。
您也可以使用 arraylist
如此使用可变变量
let mut arr = arraylist![];
arr.add(1).add(2).add(3).add(4).add(5).finish();
arr.print(); // [1, 2, 3, 4, 5]
// or use
println!("{}", arr); // same result as above
请注意,在可变对象 'object' 上调用函数 finish
时,您将获得一个不可变对象。您可以将它们全部链接起来,得到一个不可变的变量。
// you can create, add, and assign or print it all out
// like so
ArrayList::new()
.add("lagos")
.add("enugu")
.add("cairo")
.finish()
.print(); // ["lagos", "enugu", "cairo"]
// or assign
let places = ArrayList::new().ad(..)..finish();
places.print();
尝试在 Rust 中使用原生的 vec
来实现这个功能
let al = arraylist![].add("bruno").add("b").add("🦀")
.add("ß").add("བོད་སྐད་ལ").finish();
// a for_each macro, takes an immutable variable and a closure
// each of the string in the arraylist becomes a titled case
for_each!(al, |a| {
let mut upper = a.chars().collect::<Vec<_>>();
upper[0] = upper[0].to_ascii_uppercase();
upper.iter().fold(String::from(""), |mut a, b| {
a.push(*b);
a
})
})
.print(); // ["Bruno", "B", "🦀", "ß", "བ\u{f7c}ད་ས\u{f90}ད་ལ"]
ArrayList 方法
arraylist
使用了 Java、JavaScript、Python 等语言中常用的函数/方法名称。因此,下面展示的方法易于使用。我打算展示并演示每个方法的使用方式。但请注意,每个程序员的表达都受其知识量的限制。
以下是在 ArrayList
模块中可用的方法列表
-
add
pub fn add(&mut self) -> &ArrayList<T>
- 将一个值推入可变实例的空或非空 ArrayList 中。列表的长度增加 1。
let al = ArrayList::new() .add("Lagos") .add("Abuja") .finish();
-
add_all
pub fn add_all(&self, collection: &[T])
- 接受一个切片引用,并将切片中的每个元素追加到列表末尾。使用底层
vec
的扩展函数。列表的长度增加切片中元素的数量。列表的容量也相应调整。
let al = arraylist![1, 2]; al.add_all(&[3, 4, 5]); al.print(); // [1, 2, 3, 4, 5]
- 接受一个切片引用,并将切片中的每个元素追加到列表末尾。使用底层
-
add_all_at_index
pub fn add_all_at_index(&self, idx: usize, collection: &[T])
- 此函数接受两个参数;要插入的集合的起始索引。以及要插入的切片引用。它在从切片参数中添加值时将列表中的值向右移动。注意,起始索引 必须 不大于列表本身的长度。如果起始索引大于列表的长度或大小,您的代码将崩溃。
let al = arraylist![1, 2, 3]; al.add_all_at_index(1, &[4, 5, 6]); al.print(); // [1, 4, 5, 6, 2, 3]
-
cap
pub fn cap(&self) -> usize
- 返回列表的容量。
println!( "{}", ArrayList::start_with(&["coke", "fanta", "pepsi", "chapman"]).cap() );
-
clear
pub fn clear(&self)
- 清除:从列表中移除所有元素。
let al = arraylist![1, 2, 3]; al.clear(); al.print(); // []
-
clone
pub fn clone(&self) -> ArrayList<T>
- 返回一个新的 ArrayList 实例,具有相同的元素。它不是一个引用。通过 clone 方法对元素进行的更改 不会 以任何方式影响其他实例。
let new_clone = al.clone(); new_clone.push(1); new_clone.push(3); new_clone.print(); // [1, 3] al.print(); // []
-
contains
pub fn contains(&self, value: T) -> bool
- 如果列表包含参数的值,则返回 true。
let players = arraylist!["Yekini", "Pele", "Ronaldo", "Messi"]; println!("{}", players.contains("Yakubu")); // false println!("{}", players.contains("Ronaldo")); // true
-
copy
pub fn copy(&self) -> &ArrayList<T>
- 返回一个 ArrayList 实例的引用 "副本"。对其中一个所做的任何更改都会反映在另一个上。这与
clone
方法不同。注意,您可以对该实例进行多次复制。
let new_copy = al.copy(); new_copy.push(1); new_copy.push(3); al.push(0); new_copy.print(); // [1, 3, 0] al.print(); // [1, 3, 0]
- 返回一个 ArrayList 实例的引用 "副本"。对其中一个所做的任何更改都会反映在另一个上。这与
-
default
pub fn default(&self) -> ArrayList<T>
- 实现 ArrayList 的 Default 特性。返回一个具有每个元素默认值的新的 ArrayList 实例。
#[derive(Debug, Clone, PartialEq)] struct Person<'a> { name: &'a str, age: u32, } let array = ArrayList::<Person>::default(); array.print(); // [] array.push(Person { name: "boris", age: 23, }); array.print(); // [Person { name: "boris", age: 23 }
-
ensure_capacity
pub fn ensure_capacity(size: usize) -> ArrayList<T>
- 构造一个新的空 ArrayList,具有指定的容量。
let na: ArrayList<u8> = ArrayList::ensure_capacity(10); println!("{}", na.cap()); // 10
-
finish
pub fn finish(&self) -> ArrayList<T>
- 返回一个不可变的
arraylist
。通常在调用add
函数后调用,该函数创建一个可变列表并将值推入列表。finish
是调用以获得所需不可变变量的函数。
let al = arraylist![] .add("Lagos") .add("Abuja") .finish(); // immutable al.print(); // ["Lagos", "Abuja"]
- 返回一个不可变的
-
for_each
pub fn for_each(&self, f: fn(T))
- 它接受一个闭包,并在列表中的每个元素上执行闭包中的操作。但它不会更改列表的元素。
// square all odd numbers let nums = arraylist!(1, 2, 3, 4, 5); nums.for_each(|a| { println!( "{}", match a % 2 != 0 { true => a * a, false => a, } ) }); nums.print(); // [1, 2, 3, 4, 5] // if you want nums to change use macro `for_each!` instead
-
from_slice
pub fn from_slice(collection: &[T]) -> ArrayList<T>
- 接受一个值切片的引用,并返回具有相同值的 ArrayList。
let fruits = ArrayList::from_slice(&["pineapple", "pear", "banana", "orange"]); fruits.print(); // ["pineapple", "pear", "banana", "orange"]
-
get
pub fn get(&self, index: usize) -> Option<T>
get
需要要获取值的索引。它返回一个包裹在option
变体中的指定位置的值。如果索引大于列表的长度,操作将引发恐慌。否则,它返回该索引处的值。
let fruits = ArrayList::from_slice(&["pineapple", "pear", "banana", "orange"]); // println!("{}", fruits.get(31).unwrap()); // panics println!("{}", fruits.get(3).unwrap()); // orange
-
index_in
pub fn index_in(&self, value: usize) -> Option<T>
与
get
方法类似。 -
index_of
pub fn index_of(&self, value: T) -> Option<usize>
- 接收一个参数,即要查找的值,并返回该值在列表中的索引。与
index_of
相似,它是get
和index_in
的反转。如果值不在列表中,则解包操作将引发恐慌。
//println!("{:?}", fruits.index_of("pine").unwrap()); // panics println!("{:?}", fruits.index_of("orange").unwrap()); // 3
- 接收一个参数,即要查找的值,并返回该值在列表中的索引。与
-
index_of_all
pub fn index_of_all(&self, value: T) -> Vec<usize>
- 接收一个参数,即要查找的值,并返回一个包含所有可能找到该值的索引的 usize 向量。
println!( "{:?}", "hello, world is luck to be loud" .chars() .collect::<ArrayList<_>>() .index_of_all('l') ); // [2, 3, 10, 16, 27]
-
insert
pub fn insert(&self, index: usize, value: T)
- 给定两个参数;要插入的值的索引和要插入的值。此函数将索引(或位置)指定的值移动,并“插入”新的值。如果索引大于列表长度,将引发恐慌。
let places = arraylist![].add("Lagos").add("Abuja").finish(); places.print(); // ["Lagos", "Abuja"] places.insert(1, "kumasi"); places.print(); // ["Lagos", "kumasi", "Abuja"]
-
is_empty
pub fn is_empty(&self) -> bool
如果此列表不包含任何元素,则返回 true,否则返回 false。
let al = arraylist!["yah", "yak", "kah"]; al.clear(); println!("{}", al.is_empty()); // true println!("{}", arraylist![3, 5, 7, 9].is_empty()); // false
-
len
pub fn len(&self) -> usize
- 返回列表的长度。
let al = arraylist!["yah", "yak", "kah"]; println!("{}", al.len()); // 3 al.clear(); println!("{}", al.len()); // 0
-
new
pub fn new() -> ArrayList<T>
- 使用列表类型的默认值构建一个新实例的 arraylist。
let al = ArrayList::<String>::new(); // or let al: ArrayList<String> = ArrayList::new();
-
pop
pub fn pop(&self) -> Option
- 移除并返回列表中的最后一个元素。减少列表的长度和大小。列表的容量不受影响。
let fruits = arraylist![ "orange", "pear", "pineapple", "tangerine", "apple", "strawberry" ]; println!("{}", fruits.pop().unwrap()); println!("{}", fruits.pop().unwrap()); fruits.print(); // ["orange", "pear", "pineapple", "tangerine"]
-
print
pub fn print(&self)
- 打印出列表中的元素。调用
print
比使用 rust 中提供的宏println!
更直观。
let fruits = arraylist![ "orange", "pear", "pineapple", "tangerine", "apple", "strawberry" ]; fruits.print(); //["orange", "pear", "pineapple", "tangerine", "apple", "strawberry"]
- 打印出列表中的元素。调用
-
push
pub fn push(&self, value: T) -> bool
- 将指定元素追加到此列表的末尾。但与
add
不同,它不会使列表可变来完成此操作。尽管它类似于add
,但它不能像方法add
那样用于“构建器”设计方式。返回一个布尔值。
let al: ArrayList<i32> = ArrayList::new(); al.push(-34); al.push(39); al.push(25); al.print(); // [-34, 39, 25]
- 将指定元素追加到此列表的末尾。但与
-
push_on_index
pub fn push_on_index(&self, index: usize, value: T)
- 接收两个参数;要插入的索引和要插入的值。它的工作方式与
insert
方法完全相同。
let al = arraylist![1, 2, 3]; al.push_on_index(1, 7); al.push_on_index(0, 9); al.print(); // [9, 1, 7, 2, 3]
- 接收两个参数;要插入的索引和要插入的值。它的工作方式与
-
remove
pub fn remove(&self, index: usize) -> T
- 它移除并返回由提供的索引参数指定的列表中的元素。它也减少了列表的长度。如果索引大于列表长度,将引发恐慌。
println!("{}", al.remove(al.len() - 1)); // 3 al.print(); // [9, 1, 7, 2] println!("{}", al.remove(2)); // 7 al.print(); // [9, 1, 2]
-
remove_if
pub fn remove_if(&self, f: fn(T) -> bool)
- 它类似于
remove
,但它不是使用索引,而是接收一个闭包作为参数,并将该闭包应用于列表的每个元素。
let al = arraylist![1, 2, 3, 4, 5, 6, 7, 8, 9]; al.print(); // [1, 2, 3, 4, 5, 6, 7, 8, 9] al.remove_if(|a| a % 2 == 0); al.print(); // [1, 3, 5, 7, 9]
- 它类似于
-
replace
pub fn replace(&self, index: usize, value: T)
- 它用提供的索引指定的新值替换指定的元素。如果索引大于列表长度,将引发恐慌。
al.replace(0, 23); al.print(); // [23, 3, 5, 7, 9]
-
size
pub fn size(&self) -> usize
- 返回列表中元素的数量。类似于方法
len
。
println!("{}", al.len()); // 5
- 返回列表中元素的数量。类似于方法
-
start_with
pub fn start_with(collection: &[T]) -> ArrayList<T>
- 使用从参数提供的切片引用构建并返回一个 Arraylist
ArrayList<T>
,arraylist 的类型由提供的切片的类型推断得出。类型也可以指定。
let nums = ArrayList::start_with(&[1, 2, 3, 4, 5, 6]); nums.print(); // [1, 2, 3, 4, 5, 6]
- 使用从参数提供的切片引用构建并返回一个 Arraylist
-
sub_list
pub fn sub_list(&self, start: usize, stop: usize) -> Option<ArrayList>
- 从列表中返回所有索引在起始索引(包含)和结束索引(不包含)之间的元素。如果结束索引大于列表长度,则引发恐慌。
let nums = ArrayList::start_with(&[1, 2, 3, 4, 5, 6]); nums.print(); // [1, 2, 3, 4, 5, 6] nums.sub_list(1, 4).unwrap().print(); // [2, 3, 4]
-
to_vec
pub fn to_vec(&self) -> Vec
- 将列表的元素转换为并返回一个向量。这实际上非常棒,因为 Rust 的
vec
有很多方法,而这个包装器没有实现。将arraylist
转换为 vec 使得可以使用向量中的许多方法。
- 将列表的元素转换为并返回一个向量。这实际上非常棒,因为 Rust 的
待办事项
[] 执行更多复杂场景的测试和基准测试。