[英]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.