如何从特定模块创建包含所有修饰函数的向量? [英] How to create a vector of all decorated functions from a specific module?
问题描述
我有一个文件main.rs
和一个文件rule.rs
.我想在rule.rs
中定义要包含在Rules::rule
向量中的函数,而不必一一推送.我希望有一个循环来推动它们.
I have a file main.rs
and a file rule.rs
. I want to define functions in rule.rs
to be included in the Rules::rule
vector without having to push them one by one. I'd prefer a loop to push them.
main.rs :
struct Rules {
rule: Vec<fn(arg: &Arg) -> bool>,
}
impl Rules {
fn validate_incomplete(self, arg: &Arg) -> bool {
// iterate through all constraints and evaluate, if false return and stop
for constraint in self.incomplete_rule_constraints.iter() {
if !constraint(&arg) {
return false;
}
}
true
}
}
rule.rs :
pub fn test_constraint1(arg: &Arg) -> bool {
arg.last_element().total() < 29500
}
pub fn test_constraint2(arg: &Arg) -> bool {
arg.last_element().total() < 35000
}
Rules::rule
应填充test_constraint1
和test_constraint2
.
在Python中,我可以在要包含在Vec
中的约束之上添加装饰器@rule_decorator
,但是在Rust中看不到装饰器.
In Python, I could add a decorator @rule_decorator
above the constraints which you want to be included in the Vec
, but I don't see an equivalent in Rust.
在Python中,我可以使用dir(module)
查看所有可用的方法/属性.
In Python, I could use dir(module)
to see all available methods/attributes.
Python变体:
class Rules:
def __init__(self, name: str):
self.name = name
self.rule = []
for member in dir(self):
method = getattr(self, member)
if "rule_decorator" in dir(method):
self.rule.append(method)
def validate_incomplete(self, arg: Arg):
for constraint in self.incomplete_rule_constraints:
if not constraint(arg):
return False
return True
使用rule.py文件:
With the rule.py file:
@rule_decorator
def test_constraint1(arg: Arg):
return arg.last_element().total() < 29500
@rule_decorator
def test_constraint1(arg: Arg):
return arg.last_element().total() < 35000
所有带有rule_decorator
的功能都将添加到self.rule
列表中,并由validate_incomplete
功能选中.
All functions with a rule_decorator
are added to the self.rule
list and checked off by the validate_incomplete
function.
推荐答案
Rust与Python没有相同的反射功能.特别是,您不能在运行时遍历模块的所有功能.至少您不能使用内置工具来做到这一点.可以编写所谓的过程宏,使您可以向函数中添加自定义属性,例如#[rule_decorator] fn foo() { ... }
.使用proc宏,您几乎可以执行任何操作.
Rust does not have the same reflection features as Python. In particular, you cannot iterate through all functions of a module at runtime. At least you can't do that with builtin tools. It is possible to write so called procedural macros which let you add custom attributes to your functions, e.g. #[rule_decorator] fn foo() { ... }
. With proc macros, you can do almost anything.
但是,为此,使用proc宏的方法过于工程化(我认为).就您而言,我只列出所有要包含在向量中的函数:
However, using proc macros for this is way too over-engineered (in my opinion). In your case, I would simply list all functions to be included in your vector:
fn test_constraint1(arg: u32) -> bool {
arg < 29_500
}
fn test_constraint2(arg: u32) -> bool {
arg < 35_000
}
fn main() {
let rules = vec![test_constraint1 as fn(_) -> _, test_constraint2];
// Or, if you already have a vector and need to add to it:
let mut rules = Vec::new();
rules.extend_from_slice(
&[test_constraint1 as fn(_) -> _, test_constraint2]
);
}
有关此代码的一些注意事项:
A few notes about this code:
- 我用
u32
替换了&Arg
,因为它与问题无关.请忽略有关StackOverflow问题的不必要的详细信息. - 我在数字文字中使用了
_
以提高可读性. - 奇怪的
as fn(_) -> _
强制转换很可惜.您可以在这个问题.
- I replaced
&Arg
withu32
, because it doesn't have anything to do with the problem. Please omit unnecessary details from questions on StackOverflow. - I used
_
in the number literals to increase readability. - The strange
as fn(_) -> _
cast is sadly necessary. You can read more about it in this question.
这篇关于如何从特定模块创建包含所有修饰函数的向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!