I want to keep a list of filter functions and tag the items by the filters that return true. This is getting close but not quite.
我想保留一个筛选器函数列表,并通过返回True的筛选器来标记这些项目。这已经很接近了,但还不完全是。
fn adf(_bs: Bs) -> bool {
true
}
fn bodens(_bs: Bs) -> bool {
false
}
#[derive(Clone, Copy)]
struct Bs;
struct MyTagger;
impl MyTagger {
fn from_tree(&self, tree: Vec<Bs>) -> Vec<String> {
let mut fns: Vec<&dyn Fn(Bs) -> bool> = Vec::new();
fns.push(&adf);
fns.push(&bodens);
let mut res = Vec::new();
for path in tree {
for adf in fns.iter() {
if adf(path) {
res.push(std::stringify!(adf).to_string());
}
}
}
res
}
}
The main problem is std::stringify! always returns "adf" possibly the variable name i declared as adf.
主要问题是std::stringify!总是返回“ADF”,可能是我声明为ADF的变量名。
The second problem is, I need to manually manage the list as I define new filtering functions, basically push them into fns
array, and increase the static array's length.
第二个问题是,在定义新的过滤函数时,我需要手动管理列表,基本上将它们推入FNS数组,并增加静态数组的长度。
更多回答
Is the list of filtering functions constant?
过滤函数列表是常量吗?
For your first problem, you don't have to stringify anything, you can just store everything as fn(Bs) -> bool
(static function pointers). You can store those in collections and check them for equality.
对于你的第一个问题,你不需要对任何东西进行字符串化,你可以把所有东西都存储为fn(Bs)-> bool(静态函数指针)。你可以将它们存储在集合中,并检查它们是否相等。
For the second issue, maybe you could define the predicates as anonymous functions in a static slice and identify them by their index:
对于第二个问题,也许您可以将谓词定义为静态切片中的匿名函数,并通过它们的索引来标识它们:
static PREDICATES: &[fn(Bs) -> bool] = &[
|_| true,
|_| true,
|_| true,
];
If you still need a good identification could always associate a name somewhat directly:
如果你仍然需要一个好的身份证明,你可以在一定程度上直接联系一个名字:
static PREDICATES: &[(&str, fn(Bs) -> bool)] = &[
("foo", |_| true),
("bar", |_| true),
("baz", |_| true),
];
or maintain a second separate slice of names.
或者保留第二个单独的名字片段。
Either way in those cases you might want to store the index of the predicate function(s) rather than the function pointers, as that makes retrieving the name easier (also depending on context / name you could just identify the predicate by their index).
无论采用哪种方式,在这些情况下,您都可能希望存储谓词函数(S)的索引,而不是函数指针,因为这样可以更容易地检索名称(还可以根据上下文/名称,您只需通过其索引来标识谓词)。
I would go with one of Masklinn's approaches, but if you want to generate the string based on the function names you can do so, too, using a macro (where stringify
works similar to what you probably expected):
我会采用Masklinn的一种方法,但如果您想要基于函数名生成字符串,您也可以使用宏(其中stringify的工作方式与您可能预期的类似):
pub fn from_tree(&self, tree: Vec<Bs>) -> Vec<&'static str> {
macro_rules! doit {
($($adf:expr),* $(,)?) => {{
let mut res = Vec::new();
for path in tree {
$(
if $adf(path) {
res.push(stringify!($adf));
}
)*
}
res
}}
}
doit!(
adf,
bodens,
)
}
If the list of predicates becomes long or frequently changes you can also generate the PREDICATES
with a macro to avoid repeating the function names:
如果谓词列表变长或频繁更改,还可以使用宏来生成谓词,以避免重复函数名:
macro_rules! predicates {
($($pred:expr),* $(,)?) => {{
[
$((stringify!($pred), $pred)),*
]
}}
}
static PREDICATES: &[(&str, fn(Bs) -> bool)] = &predicates![
foo,
bar,
baz,
];
更多回答
我是一名优秀的程序员,十分优秀!