Rust的类型系统并没有对大小进行概括,但是type associated constants(Rust 1.20中的新增内容)我认为通过声明一个恒定的大小可能有一些方法可以解决这个问题。在一个类型。
给定在Rust中对固定大小数组进行操作的函数,是否可能/实际使用类型常量来声明采用任意数组大小或至少预定义大小范围(1..32)的函数。
以小数学API为例:
// Cut down example of a math API
// Could be changed at compile time, otherwise quite limiting.
pub const DIMS: usize = 3;
pub fn sq(a: f64) -> f64 { a }
pub fn len_squared_vnvn(v0: &[f64; DIMS], v1: &[f64; DIMS]) -> f64 {
let mut d = 0.0;
for j in 0..DIMS {
d += sq(v0[j] - v1[j]);
}
return d;
}
fn imul_vn_fl(v0: &mut [f64; DIMS], f: f64) {
for j in 0..DIMS {
v0[j] *= f;
}
}
可以DIMS
移动到与关联类型相关的常量,以便......
imul_vn_fl
等函数可以与任意固定大小的数组一起使用。[f64; SOME_CONSTANT_NUMBER]
或更可能的是零成本转换为包装[f64; #]
的类型并定义DIMS
类型常量std::convert::From
/ Into
,以避免在每次通话时显式写入演员表。我想象这样的事情:
// this would be a macro to avoid re-writing for every size.
type f64v3 = u64;
impl VectorSize for f64v3 {
const usize DIMS = 3;
}
// end macro
fn example() {
let var: [f64; 3] = [0.0, 1.0, 2.0];
imul_vn_fl(var, 0.5);
// ...
}
答案 0 :(得分:1)
相关常数的(当前?)限制是它们不能在泛型类型上调用。 即,按照您的示例,使用关联的常量,您可以执行此操作:
trait VectorSize {
const DIMS: usize;
}
impl VectorSize for u64 {
const DIMS: usize = 3usize;
}
fn imul_vn_fl(v0: &mut [f64; u64::DIMS], f: f64) {
for j in 0..u64::DIMS {
v0[j] *= f;
}
}
但您最终希望能够使imul_vn_fl
通用,并让它使用您的类型上定义的DIMS。这是关联常数仍然不足的地方(参见"缺点" https://github.com/rust-lang/rust/issues/29646中的第一个)
// this does not compile, unfortunately; T must be a concrete type
fn imul_vn_fl<T>(v0: &mut [f64; T::DIMS], f: f64)
where
T:VectorSize
{
for j in 0..T::DIMS {
v0[j] *= f;
}
}