gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:28:31 25 4
gpt4 key购买 nike

我在读取页表的结构定义时遇到了这个问题(在面向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 条板箱,该条板箱的工作方式与您尝试的类似,但是可以为您完成所有类型级别的样板工作。

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()
);
}
类型 U0U1U2,...表示无符号整数0、1、2 ...

关于generics - 如何在Rust中定义具有不同const参数的结构家族?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64675198/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com