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);
// ...
}
最佳答案
关联常量的(当前?)限制是它们不能在泛型类型上调用。 即,按照您的示例,使用关联的常量,您可以执行以下操作:
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;
}
}
关于types - 类型关联常量可以用于将数组大小参数推广到函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46136890/