Generics 如何在Rust中定义具有不同常量参数的结构族?

Generics 如何在Rust中定义具有不同常量参数的结构族?,generics,rust,traits,type-level-computation,Generics,Rust,Traits,Type Level Computation,我在阅读页表的结构定义(用于针对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 Tab

我在阅读页表的结构定义(用于针对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;
}
这段锈迹代码似乎不是很聪明。我想知道我是否可以参数化级别编号,例如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;
}
#包括
#包括
模板
结构级{
类型DEF级别下一级;
};
模板
结构级{};
int main(){
//下面的输出将给出“1”。
//它检查类型`Level::NextLevel::NextLevel'`
//类型'Level::NextLevel'实际上是同一类型。
标准::cout

不稳定的语言特性在允许您执行的操作方面非常有限。正如您所发现的,您不能在类型参数中使用包含泛型常量的表达式

然而,在stable Rust中,您可以使用板条箱,其工作方式与您尝试的方式类似,但所有类型级别的样板都适合您

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()
    );
}
使用std::ops::Sub;
使用typenum::{Unsigned,U1,U2,U3};//1.12.0
结构层(N);
impl级别{
fn value()->usize{
N::to_usize()
}
}
特征层次结构{
NextLevel型;
}
级别的impl HierarchyCalleLevel
哪里
N:Sub+无符号,
::输出:未签名,
{
类型NextLevel=级别;
}
fn main(){
断言(
::NextLevel::value(),
级别:::值()
);
}
类型
U0
U1
U2
,…表示无符号整数0,1,2

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