我在阅读页表的结构定义时遇到了这个问题(在针对 x86_64 平台的操作系统源代码中使用)。定义如下:
pub trait TableLevel {}
pub enum Level4 {}
pub enum Level3 {}
pub enum Level2 {}
pub enum Level1 {}
impl TableLevel for Level4 {}
impl TableLevel for Level3 {}
impl TableLevel for Level2 {}
impl TableLevel for Level1 {}
pub trait HierarchicalLevel: TableLevel {
type NextLevel: TableLevel;
}
impl HierarchicalLevel for Level4 {
type NextLevel = Level3;
}
impl HierarchicalLevel for Level3 {
type NextLevel = Level2;
}
impl HierarchicalLevel for Level2 {
type NextLevel = Level1;
}
这段 Rust 代码看起来不太聪明。我想知道是否可以参数化级别编号,例如1,2,3,4。使用 C++,我可以轻松实现这一点:
#include <type_traits>
#include <iostream>
template <unsigned L>
struct Level {
typedef Level<L-1> NextLevel;
};
template <>
struct Level<1> {};
int main() {
// The output below will give "1".
// It checks the type `Level<3>::NextLevel::NextLevel`
// and the type `Level<2>::NextLevel` are indeed the same type.
std::cout
<< std::is_same<Level<3>::NextLevel::NextLevel,
Level<2>::NextLevel>::value
<< std::endl;
return 0;
}
我尝试在 Rust 中做同样的事情,但我做不到,因为 Rust 不允许我使用常量参数进行算术运算。
#![feature(min_const_generics)]
struct Level<const LEVEL: usize> {}
impl <const LEVEL: usize> TableLevel for Level<LEVEL> {}
impl <const LEVEL: usize> HierarchicalLevel for Level<LEVEL> {
// Error message from the compiler:
// generic parameters may not be used in const operations
// cannot perform const operation using `LEVEL`
// help: const parameters may only be used as standalone arguments, i.e. `LEVEL`
type NextLevel = Level<{LEVEL - 1}>;
}
是否可以在 Rust 的当前版本(可能是每晚版本)中参数化级别号?
最佳答案
不稳定的语言功能,min_const_generics
它可以让你做的事情非常有限。正如您所发现的,您不能在类型参数中使用涉及泛型常量的表达式。
但是,在稳定的 Rust 中,您可以使用 typenum
crate,它的工作方式与您尝试的方式类似,但会为您执行所有类型级样板。
use std::ops::Sub;
use typenum::{Unsigned, U1, U2, U3}; // 1.12.0
struct Level<N: Unsigned>(N);
impl<N: Unsigned> Level<N> {
fn value() -> usize {
N::to_usize()
}
}
trait HierarchicalLevel {
type NextLevel;
}
impl<N> HierarchicalLevel for Level<N>
where
N: Sub<U1> + Unsigned,
<N as Sub<U1>>::Output: Unsigned,
{
type NextLevel = Level<<N as Sub<U1>>::Output>;
}
fn main() {
assert_eq!(
<Level::<U3> as HierarchicalLevel>::NextLevel::value(),
Level::<U2>::value()
);
}
类型U0
、U1
、U2
、...表示无符号整数0、1、2、...
关于generics - 如何在 Rust 中定义具有不同 const 参数的结构族?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64675198/