Wee*_*ezy 1 generics rust const-generics
我不是 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
...
5 | const l: u32 = K + 1;
| ^ use of generic parameter from outer function
For more information about this error, try `rustc --explain E0401`.
error: could not compile `playground` due to previous error
Run Code Online (Sandbox Code Playgroud)
我的理解是 const 泛型的当前状态拒绝const generic从其他const genericss 实例化 new ,因为const generics 在成为值之前是类型。爱荷华州,K在
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
...
5 | const l: u32 = K + 1;
| ^ use of generic parameter from outer function
For more information about this error, try `rustc --explain E0401`.
error: could not compile `playground` due to previous error
Run Code Online (Sandbox Code Playgroud)
是一种类型,而不是由 定义的通常的 const 值,const K : u32 = 1;尽管我在这里强烈提到,错误消息并未指出其背后的原因。
当我们尝试这样做时会出现另一个问题:
fn foo<const K: u32> () {}
Run Code Online (Sandbox Code Playgroud)
错误:
error[E0207]: the const parameter `L` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:3:27
|
3 | impl<const K : u32, const L: u32> Base<K> {
| ^ unconstrained const parameter
|
= note: expressions using a const parameter must map each value to a distinct output value
= note: proving the result of expressions other than the parameter are unique is not supported
Run Code Online (Sandbox Code Playgroud)
有什么方法可以实现我在这里尝试做的事情,或者我应该放弃 const 泛型并使用常规字段来定义此处的基数?
我的理解是 const 泛型的当前状态拒绝从其他 const 泛型实例化新的 const 泛型,因为 const 泛型在成为值之前是类型
这不是真的,但您的代码存在多个问题。
首先,正如编译器指出的那样,const L 函数内部不能引用函数的泛型参数K。这是因为consts 是单独编译的,即使在函数内部也是如此(唯一的区别是函数外部的代码无法访问,即作用域)。
您应该嵌入计算:
pub const fn base_bump<const K: u32, const L: u32>(b: Base<K>) -> Base<L> {
Base::<{ K + 1 }> {}
}
Run Code Online (Sandbox Code Playgroud)
但这仍然存在多个问题。首先,您声明您要返回调用者选择的值,但实际上您返回的是常量Base而不是。您需要像这样声明该函数:LK + 1L
pub const fn base_bump<const K: u32>(b: Base<K>) -> Base<{ K + 1 }> {
Base::<{ K + 1 }> {}
}
Run Code Online (Sandbox Code Playgroud)
但这会出错:
error: generic parameters may not be used in const operations
--> src/lib.rs:2:74
|
2 | pub const fn base_bump<const K: u32, const L: u32>(b: Base<K>) -> Base<{ K + 1 }> {
| ^ cannot perform const operation using `K`
|
= help: const parameters may only be used as standalone arguments, i.e. `K`
error: generic parameters may not be used in const operations
--> src/lib.rs:3:14
|
3 | Base::<{ K + 1 }> {}
| ^ cannot perform const operation using `K`
|
= help: const parameters may only be used as standalone arguments, i.e. `K`
Run Code Online (Sandbox Code Playgroud)
因为这东西需要#![feature(generic_const_exprs)]。有了它,它可以工作,但会发出警告:
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
--> src/lib.rs:1:12
|
1 | #![feature(generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
Run Code Online (Sandbox Code Playgroud)
请参阅我的这个答案,了解为什么此功能特别困难。