rust - Rust 是否支持具有运行时确定值的常量泛型类型?

标签 rust const-generics

考虑 const-generic 数据结构的经典示例:方矩阵。

struct Matrix<T, const N: usize> {
    inner: [[T; N]; N]
}

我想返回一个结构体,其 const 参数是动态定义的:

fn read_matrix() -> ??? {
    let n: usize = todo!() // the N is decided dynamically
    let r: Box<Matrix<u8, {n}>> = todo!();
    r
}

但是:

  • Rust 会提示 n不是常数
  • 我无法编写合适的返回类型:fn read_matrix<const N: usize>() -> Matrix<u8, N>是不够的,因为它让调用者选择 N,我希望 N 在运行时确定。

我可以通过定义特征来解决第二个限制:

trait DynamiMatrix {
   fn size(&self) -> usize;
   fn some_method(&self);
   ...
}

impl<T, const N: usize> DynamicMatrix for Matrix<T,N> {
   fn size(&self) -> usize { N };
   fn some_method(&self){ ... }
   ...
}

但是,对于构造,我能尝试的最好的是:

fn read_array_pair() -> Box<dyn DynamicMatrix> {
  let n: usize = todo!();
  let m = Box::new(Matrix { inner: [[0; n]; n] });
  todo!(); // fill up m
  m
}

Rust 仍然会提示 n 不是常量。

有什么办法可以实现吗?如果可能而不回退到嵌套 Vec s,因为我希望我的平方不变量被强制执行?

最佳答案

Const 参数是有意设计的,以便它们在编译时始终是已知的。就像程序中有关类型的大多数信息一样,编译器会在运行时删除它们而不保留这些信息。 所以简短的回答是否定的,而且不太可能在运行时直接指定这种 const 参数。

但是,创建可能包含编译时或运行时信息的通用结构有已知的解决方法,它们甚至早于 const 参数。

考虑 ndarray::ArrayBase 的这个简化定义:

pub struct ArrayBase<S, D> {
    /// Data buffer / ownership information. (If owned, contains the data
    /// buffer; if borrowed, contains the lifetime and mutability.)
    data: S,
    /// The lengths of the axes.
    dim: D,
    /// The element count stride per axis.
    strides: D,
}

此定义在其元素来源 S 及其维数D 上进行了参数化。 D,通常通过原语 Dim 实现, 那么在这两种情况下都是通用的:

  • 对于固定数量的维度,例如 Array2 , D = Ix2 , 使用户能够传递 [usize; 2] 索引数组中的元素。
  • 如果编译时维数未知,则有ArrayD,其中D = IxDyn用户可以将 Deref 的任何内容传递给 [usize] 进行索引。

结论是您可能有兴趣更改结构和特征的设计,以便将这些细节(无论是在编译时还是在运行时推断)编码为类型参数而不是 const 参数。

关于rust - Rust 是否支持具有运行时确定值的常量泛型类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68907965/

相关文章:

file - 以固定大小的 block 读取二进制文件并将所有这些 block 存储到 Vec 中的正确方法是什么?

rust - 在当前范围内找不到类型 *mut Y 的名为 X 的方法

rust - "parameter ` 'a` 从未使用 "error when ' a 用于类型参数绑定(bind)

arrays - 如何修改数组的最后一项?

rust - 使用 Rust 的 openssl 库加密/解密大文本

generics - 满足与 const 泛型表达式绑定(bind)的特征,这可能吗?

generics - 为所有使用 const 参数实现特征的类型实现特征

generics - 如何初始化常量泛型数组?