types - 类型关联常量可以用于将数组大小参数推广到函数吗?

标签 types rust

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;
    }
}

playground

关于types - 类型关联常量可以用于将数组大小参数推广到函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46136890/

相关文章:

haskell - 推断 lambda 表达式的类型

matlab - 我们可以在 Matlab 中使用混合类型的矩阵吗……如何操作?

rust - 接收错误[E0276] : impl has stricter requirements than trait with generics

rust - 为什么 Rust 需要 `if let` 语法?

c# - 类型推断变量

node.js - 在 mongoose .d.ts 中分配自定义方法,这样我就可以在 typescript 中使用 mongoose 的任何地方使用它们

java - 无法在 java 中从 String 转换为 float

string - 获取句子中单词的第一个字母

字符串向量报告错误 "str does not have a constant size known at compile time"

unit-testing - 有没有一种方法可以测试 rust 中的宏?