简体   繁体   English

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

[英]How to define a family of structs with different const parameters in Rust?

I ran into this problem while reading the struct definitions for page tables (used in an operating system source code targeting x86_64 platform).我在读取页表的结构定义时遇到了这个问题(在面向 x86_64 平台的操作系统源代码中使用)。 The definitions are shown below:定义如下所示:

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

This piece of Rust code seems not very clever.这段 Rust 代码似乎不是很聪明。 I'm wondering if I can parameterize the level number, eg 1,2,3,4.我想知道我是否可以参数化级别编号,例如 1,2,3,4。 With C++, I can achieve this easily:使用 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;
}

I tried to do the same thing in Rust, but I couldn't because Rust wouldn't allow me do to arithmetic operations with constant parameters.我试图在 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}>;
}

Is it possible to parameterize the level number in the current version (possibly nightly) of Rust?是否可以在 Rust 的当前版本(可能是每晚)中参数化级别编号?

The unstable language feature, min_const_generics is quite limited in what it lets you do.不稳定的语言特性min_const_generics在它允许你做的事情上非常有限。 As you discovered, you can't use expressions involving generic constants in type arguments.正如您所发现的,您不能在类型参数中使用涉及泛型常量的表达式。

However, in stable Rust, you can use the typenum crate, which works in a similar way to what you were trying, but does all of the type-level boilerplate for you.但是,在稳定的 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()
    );
}

The types U0 , U1 , U2 ,... represent the unsigned integers 0, 1, 2,...类型U0 , U1 , U2 ,... 代表无符号整数 0, 1, 2,...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对接受具有共同属性的不同结构的 Rust 函数进行重复数据删除? - How to deduplicate Rust functions accepting different structs with common properties? 通用结构传染媒介在铁锈的 - Vector of Generic Structs in Rust 如何在Rust中收集通用类型的结构? - How do I make a Collection of Generically Typed Structs in Rust? 在Rust中将const除以泛型 - Dividing a const by a generic in Rust 用 Rust 结构驯服终生传染 - Taming Lifetime Contagion with Rust Structs 如何在不装箱的情况下存储不同类型的结构 - How to store structs of different types without boxing 如何使用Reflection Emit定义具有相同名称和不同类型参数的多个类型? - How can I define multiple types with the same name and different type parameters using Reflection Emit? 如何仅使用一个类型参数在 Rust 中定义通用 function - How to use only one type parameter to define a generic function in Rust 如何泛化参数是具有不同属性的不同结构的函数? - How to generic a function where params are different structs with different properties? 如何建立一个将不同类的向量作为参数的函数族? - How to make a family of functions which will take as an argument vectors of different classes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM