我有一个文件main.rs
和一个文件rule.rs
。我想在rule.rs
中定义函数以包含在Rules::rule
向量中,而不必逐个推送它们。我更喜欢循环来推动它们。
卖弄.人生:
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
}
}
入了.人生:
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中,我可以在你想要包含在@rule_decorator
中的约束上面添加一个装饰器Vec
,但是我没有看到Rust中的等价物。
在Python中,我可以使用dir(module)
来查看所有可用的方法/属性。
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文件:
@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
函数进行检查。
Rust没有与Python相同的反射功能。特别是,您无法在运行时迭代模块的所有函数。至少你不能用内置工具做到这一点。可以编写所谓的过程宏,它允许您向函数添加自定义属性,例如#[rule_decorator] fn foo() { ... }
。使用proc宏,您几乎可以做任何事情。
但是,使用proc宏来进行过度设计(在我看来)。在您的情况下,我只列出要包含在向量中的所有函数:
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]
);
}
关于此代码的一些注意事项:
&Arg
取代了u32
,因为它与问题没有任何关系。请在StackOverflow上的问题中省略不必要的细节。_
来提高可读性。as fn(_) -> _
演员是可悲的必要。你可以在this question上阅读更多相关信息。