我想编写一个通用函数count_calls
,该函数调用接受函数指针(lambda)的函数f
,其中count_calls
统计函数f
调用给定lambda函数的次数。
我对这个方法感到困惑(Playground)。
fn count_calls<S, F>(s: S, f: F) -> u32
where
S: Clone,
F: Sized + FnMut(Fn() -> S) -> (),
{
let mut counter: u32 = 0;
f(|| {
counter += 1;
s.clone()
});
counter
}
#[cfg(test)]
mod stackoverflow {
use super::*;
fn f(p: fn() -> i32) {
p();
p();
}
#[test]
fn test() {
let counts = count_calls(3, f);
assert_eq!(counts, 2);
}
}
我遇到了错误:
这里我遇到了错误:
error[E0277]: the size for values of type `(dyn std::ops::Fn() -> S + 'static)` cannot be known at compilation time
--> src/lib.rs:1:1
|
1 | / fn count_calls<S, F>(s: S, f: F) -> u32
2 | | where
3 | | S: Clone,
4 | | F: Sized + FnMut(Fn() -> S) -> (),
... |
12 | | counter
13 | | }
| |_^ doesn't have a size known at compile-time
|
= help: within `((dyn std::ops::Fn() -> S + 'static),)`, the trait `std::marker::Sized` is not implemented for `(dyn std::ops::Fn() -> S + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because it appears within the type `((dyn std::ops::Fn() -> S + 'static),)`
= note: required by `std::ops::FnMut`
有人知道如何修复这个问题吗?
[编辑]
我认为使用 Box<Fn()->S>
可能是一种解决方案。但如果可能的话,我更喜欢仅使用堆栈的解决方案。
f
的匿名闭包类型,这比我想象的要棘手得多...我很兴奋看到 Rust 专家们如何处理这个问题。 - turbulencetoomap
或flat_map
。但映射函数采用函数指针,允许它请求额外的数据。该映射提供数组的项(每个请求仅提供一个)。如果有数据被请求并且所有项都由映射提供,则映射会提供前一个迭代器的下一项。您可以将其视为 SQL 中的交叉连接。但计算数组是昂贵的,只有在极少数情况下才需要。这就是为什么通过函数指针进行惰性计算的原因。 - Matthias