我有一个类型
Network
的实现以及相关函数 pub fn is_acyclic(&mut self) -> bool
。我正在尝试创建一个通用函数 fn run_test(n: usize, f: fn()->bool)
,这样我就可以传递与 Network::is_acyclic
相同签名的函数,这样我就可以将这些函数应用于构造的 Network
s n
次。请参阅下面的代码块。
#[test]
fn acyclic() {
assert!(run_test(10, Network::is_acyclic))
}
...
fn run_test(n: usize, f: fn()->bool) -> bool {
let mut results = vec![];
for _ in 0..n {
let (l,r) = gen_test_nets();
let mut net = Network::new_random(l, r);
results.push(net.f());
}
results.iter().all(|&x| x)
}
我特别遇到两个错误:
Mismatched Types ...
= note: expected fn pointer 'fn(Network<_>) -> _'
found fn item 'for<'a> fn(&'a mut Network<Node<_>>) -> _ {Network::<Node<_>>::is_acyclic}'
我收集到的信息意味着我在
Network::is_acyclic
方法中传递了 acyclic
错误。我尝试过以Network::is_acyclic()
的身份传递,我尝试过以各种形式尝试过Try
和as
,我在网上找到了类似的问题,老实说我不明白我在做什么。我还尝试了 where
定义上的 run_test
关键字,我认为它应该将参数类型强制转换为函数,尽管我不认为这是问题,因为它知道我正在尝试将函数指针作为参数(这就是我相信我想要的)。
我也尝试过这个版本的
run_test
方法,结果相同
fn run_test<T>(n: usize, f: fn(Network<T>)->bool) -> bool {
let mut results = vec![];
for _ in 0..n {
let (l,r) = gen_test_nets();
let mut net = Network::new_random(l, r);
results.push(net.f());
}
results.iter().all(|&x| x)
}
特别是,
is_acyclic
是在impl<T: Clone + PartialEq + Eq + Hash> Network<Node<T>>
中实现的,我尝试在测试方法中进行所有这些声明,但没有成功。我得到了相同的错误“预期的函数指针,找到的函数项”以及一些类似于 associated type bindings are not allowed here... assert!(run_test::<T: Clone + PartialEq + Eq + Hash>(10, Network::is_acyclic))
的额外错误。
我遇到的另一个错误是
no method named 'f' found for struct 'Network' in the current scope
中的results.push(net.f());
行上的run_test
。我不确定一旦我在该方法中正确传递函数指针为 f
后,此错误是否会自行解决。
is_acyclic
不是一个“关联函数”,它是一个方法。这意味着它以某种方式采用 self
参数。在你的例子中,由于它是 Network<Node<T>>
的特征实现的一部分,它的原型相当于:
fn is_acyclic (self: &Network<Node<T>>) -> bool;
给定一个类型为
net
的实例Network<Node<T>>
,通常使用方法调用语法net.is_acyclic()
来调用它,但也可以使用统一函数调用语法:Network::<Node::<T>>::is_acyclic (&net)
来调用它。所以在你的情况下,这应该有效:
#[test]
fn acyclic() {
// Need to replace the `?????` with the real type that `gen_test_nets`
// and `Network::new_random` create.
assert!(run_test(10, Network::<Node::<?????>>::is_acyclic))
}
...
fn run_test(n: usize, f: &Network<Node<?????>>) -> bool {
let mut results = vec![];
for _ in 0..n {
let (l,r) = gen_test_nets();
// You can find out the real type of `net` with an IDE or:
// let net: () = Network::new_random(l, r);
// which will fail to compile and the error message will give
// you the actual type.
let mut net = Network::new_random(l, r);
results.push(f (&net));
}
results.iter().all(|&x| x)
}