gpt4 book ai didi

generics - 可以将实现特征的所有类型存储在列表中并遍历该列表吗?

转载 作者:行者123 更新时间:2023-11-29 08:24:21 25 4
gpt4 key购买 nike

我为许多结构(ABC 等)实现了一个特征:

pub trait ApplicableFor: Debug + Default {
unsafe fn is_applicable_for(from: *mut u8) -> bool
where
Self: Sized;
}

我需要一个方法来查找哪个结构为此方法调用返回 true。我有代码:

unsafe fn check_applicable<T: ApplicableFor>(from: *mut u8) -> bool {
T::is_applicable_for(from, to)
}

unsafe fn find_applicable(from: *mut u8) -> ApplicableFor {
if check_applicable::<A>(from) {
A::default()
} else if check_applicable::<B>(from) {
B::default()
} else if check_applicable::<C>(from) {
C::default()
} else {
panic!("Couldn't find appicable");
}
}

在实际代码中,我有大约 20 个结构,所以我想将它们存储在某个地方并使用这样的代码以提高可读性:

unsafe fn find_applicable(from: *mut u8) -> ApplicableFor {
for T in list {
if check_applicable::<T>(from) {
T::default()
}
}
panic!("Couldn't find appicable");
}

我该如何做或如何更好地重写它?

最佳答案

不,Rust 不直接提供您需要的那种元编程功能。即,类型不是存在或可以放入集合中的具体事物。

相反,您需要代码生成。

ApplicableFor 的简化版本开始,我们可以编写一个非常结构化的 find_applicable 版本:

trait ApplicableFor {
fn is_applicable_for(from: u8) -> bool;
}

fn find_applicable(from: u8) {
if <A>::is_applicable_for(from) {
println!("Using {}", stringify!(A));
return;
}

if <B>::is_applicable_for(from) {
println!("Using {}", stringify!(B));
return;
}

if <C>::is_applicable_for(from) {
println!("Using {}", stringify!(C));
return;
}

panic!("Couldn't find any applicable types");
}

一旦我们建立了结构,那么我们就可以开始用宏抽象它了:

fn find_applicable(from: u8) {
macro_rules! find_one {
($ty:ty) => {
if <$ty>::is_applicable_for(from) {
println!("Using {}", stringify!($ty));
return;
}
}
}

find_one!(A);
find_one!(B);
find_one!(C);

panic!("Couldn't find any applicable types");
}

如果我们想重复这个“为这个类型列表做点什么”的概念怎么办?另一个宏:

macro_rules! each_type {
($one_type_macro:tt) => {
$one_type_macro!(A);
$one_type_macro!(B);
$one_type_macro!(C);
};
}

fn find_applicable(from: u8) {
macro_rules! find_one {
($ty:ty) => {
if <$ty>::is_applicable_for(from) {
println!("Using {}", stringify!($ty));
return;
}
}
}

each_type!(find_one);

panic!("Couldn't find any applicable types");
}

each_type! 的实现有太多噪音吗?创建一个宏,该宏创建另一个宏,该宏将与另一个宏一起调用:

macro_rules! gen_each_type {
($($ty:ty),*) => {
macro_rules! each_type {
($one_type_macro:tt) => {
$($one_type_macro!($ty);)*
};
}
};
}

gen_each_type![A, B, C];

关于generics - 可以将实现特征的所有类型存储在列表中并遍历该列表吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56655953/

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