7个版本
0.3.0 | 2020年11月5日 |
---|---|
0.2.0 | 2019年9月13日 |
0.1.4 | 2019年9月7日 |
#1391 在 Rust模式
42KB
794 行
vec-utils
这是一个实验性包,为Vec<T>
添加了一些有用的功能,如map
和zip_with
。这些函数允许您转换向量并尝试重用分配,如果可能的话!
use vec_utils::VecExt;
fn to_bits(v: Vec<f32>) -> Vec<u32> {
v.map(|x| x.to_bits())
}
fn sum_2(v: Vec<f32>, w: Vec<f64>) -> Vec<f64> {
v.zip_with(w, |x, y| f64::from(x) + y)
}
zip_with
仅限于接受单个额外的向量。为了克服这一限制,此包还导出了一些宏,可以接受任意数量的输入向量,并且在大多数情况下将编译成与Vec::map
和Vec::zip_with
相同的汇编代码(有时会添加一些额外的清理代码,但即使是宏解决方案的速度也和内置版本一样快)。
您可以使用zip_with
和try_zip_with
宏,如下所示:
use vec_utils::{zip_with, try_zip_with};
fn to_bits(v: Vec<f32>) -> Vec<u32> {
zip_with!(v, |x| x.to_bits())
}
fn sum_2(v: Vec<f32>, w: Vec<f64>) -> Vec<f64> {
zip_with!((v, w), |x, y| f64::from(x) + y)
}
fn sum_5(a: Vec<i32>, b: Vec<i32>, c: Vec<i32>, d: Vec<i32>, e: Vec<i32>) -> Vec<i32> {
zip_with!((a, b, c, d, e), |a, b, c, d, e| a + b + c + d + e)
}
fn mul_with(a: Vec<i32>) -> Vec<i32> {
zip_with!((a, vec![0, 1, 2, 3, 4, 5, 6, 7]), |a, x| a * x)
}
fn to_bits_no_nans(v: Vec<f32>) -> Result<Vec<u32>, &'static str> {
try_zip_with!(v, |x| if x.is_nan() { Err("Found NaN!") } else { Ok(x.to_bits()) })
}
您可以使用任意数量的输入向量,只需将它们全部放入输入元组中。请注意,第二个参数不是一个闭包,而是一种看起来像闭包的语法,即您不能预先创建一个闭包并将其作为第二个参数传递。此外,您不能在“闭包”的参数中使用通用模式,只允许使用标识符。您可以通过在“闭包”之前添加move关键字来指定是否需要移动闭包。
use vec_utils::zip_with;
fn add(a: Vec<i32>, b: i32) -> Vec<i32> {
zip_with!(a, move |a| a + b)
}
它还通过使用BoxExt
/UninitBox
api添加了重用Box<T>
分配的功能。
use vec_utils::BoxExt;
fn replace(b: Box<i32>, f: f32) -> Box<f32> {
Box::drop_box(b).init(f)
}
fn get_and_replace(b: Box<i32>, f: f32) -> (Box<f32>, i32) {
let (b, x) = Box::take_box(b);
(b.init(f), x)
}