考虑 const 通用数据结构的经典示例:方阵。
struct Matrix<T, const N: usize> {
inner: [[T; N]; N]
}
Run Code Online (Sandbox Code Playgroud)
我想返回一个其 const 参数是动态定义的结构:
fn read_matrix() -> ??? {
let n: usize = todo!() // the N is decided dynamically
let r: Box<Matrix<u8, {n}>> = todo!();
r
}
Run Code Online (Sandbox Code Playgroud)
但:
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) …Run Code Online (Sandbox Code Playgroud) 我相信下面的代码是有意义的:
trait FooConst<const N: usize> {}
trait Foo {}
impl<T: FooConst<N>, const N: usize> Foo for T {}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试编译它时,出现错误 E0207,指出该参数N是无界的。我不明白为什么,因为在我看来,这是绑定的一部分T。
我正在尝试更多地了解 const 泛型以及它们如何应用于任何维度的某些网格算法。下面是一个片段 - 如何创建一个 const 泛型参数大小的数组?
type Point<const N: usize> = [i32; N];
fn new_point<const N: usize>(x: i32, y: i32) -> Point<N> {
[x, y]
}
fn main() {
let point: Point<2> = new_point(1, 2);
println!("Point: {:?}", point)
}
Run Code Online (Sandbox Code Playgroud)
上面的结果会导致编译器错误:
error[E0308]: mismatched types
--> src/main.rs:4:5
|
3 | fn new_point<const N: usize>(x: i32, y: i32) -> Point<N> {
| -------- expected `[i32; N]` because of return type
4 | [x, y]
| ^^^^^^ expected `N`, found `2_usize`
|
= …Run Code Online (Sandbox Code Playgroud) 我正在尝试利用当前不稳定的功能,generic_const_exprs让我的库的用户知道他们生成的类型的结果尺寸。
我的用例要复杂得多,但我创建了一个带有可重现错误的最小示例。主要思想是,给定 aTensor<N>作为输入,我想输出 a Tensor<M>,其中M是{N + 1}。A是一个特质,它同时为和 forTensor<N>实现。这是代码:Constant<N>Variable<M>
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
struct Variable<const N: usize>;
struct Constant<const N: usize>;
trait Tensor<const N: usize> {
fn get_dim(&self) -> usize {
N
}
}
trait ConvertTo<Y> {
fn convert(&self) -> Y;
}
impl<const N: usize> Tensor<N> for Variable<N> {}
impl<const N: usize> Tensor<N> for Constant<N> {}
impl<const N: usize, const M: usize> ConvertTo<Constant<M>> for Variable<N> {
fn convert(&self) -> Constant<M> …Run Code Online (Sandbox Code Playgroud) 我不是 const 泛型方面的专家,但在尝试涉及对 const 泛型进行操作的新类型实例化时,我尝试了几种不同的方法,但都存在问题,例如:当尝试将此 const 泛型结构中的基数从 增加到K时K+1。
// Given a Base<K> return a Base<K+1>
pub struct Base<const K:u32> {}
pub const fn base_bump<const K: u32, const L: u32>(b: Base<K>,) -> Base<L> {
const L : u32 = K + 1;
Base::<L> {}
}
Run Code Online (Sandbox Code Playgroud)
错误 :
error[E0401]: can't use generic parameters from outer function
--> src/main.rs:5:20
|
2 | pub const fn base_bump<const K: u32, const L: u32>(
| - const parameter from outer function
... …Run Code Online (Sandbox Code Playgroud) 我想要一个表示值数组的数据结构,但它仅支持一组特定的大小并在编译时强制执行。就像是:
struct MyArray<const N: usize>([u8; N]);
Run Code Online (Sandbox Code Playgroud)
但这样的N只能是一组特定的值,而不仅仅是 可以表示的任何数字usize。例如,我希望一个结构体可以包装 a [u8; 3]、 a[u8; 6]或 a [u8; 9],但不能包装除3、6 和 9 之外的[u8; N]任何其他结构体。我需要在编译时强制执行此约束,并且最好是N类型系统。这在 Rust 中可能吗?是否有执行此操作的标准模式或板条箱?
假设我正在为数组编写一个包装类型。
struct Array<const L: usize, T> {
raw: [T;L]
}
Run Code Online (Sandbox Code Playgroud)
我有一些函数可以改变数组包装器的长度,假设该函数是串联:
impl<const L: usize, T> Array<L, T> {
fn concat<const L2: usize>(self, other: Array<L, T>) -> Array<{L + L2}, T> {todo!();}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译这段代码时,rust 编译器变得非常疯狂。认为这可能与添加与实现多个特征相对应的类型有关,我尝试使用乘法而不是加法,但这也不起作用。
我知道 Rust 可以在编译时计算某些表达式,这只是不允许的情况,还是我遗漏了一些东西?