Rust 递归闭包作为函数参数“;由于需求冲突”;
这个问题比你想象的要复杂得多 有一个递归闭包,将环境变量移入其中 下面的代码是一个有用的函数集,用于函数编程,包括: 我想知道是否可以将该闭包传递给函数,然后在该闭包中调用该函数,下面的代码会抛出一个错误Rust 递归闭包作为函数参数“;由于需求冲突”;,rust,Rust,这个问题比你想象的要复杂得多 有一个递归闭包,将环境变量移入其中 下面的代码是一个有用的函数集,用于函数编程,包括: 我想知道是否可以将该闭包传递给函数,然后在该闭包中调用该函数,下面的代码会抛出一个错误 extern crate tool; use tool::prelude::*; use std::cell::RefCell; fn main() { let a = RefCell::new(false); let fib = fix(move |f, x| {
extern crate tool;
use tool::prelude::*;
use std::cell::RefCell;
fn main() {
let a = RefCell::new(false);
let fib = fix(move |f, x| {
*a.borrow_mut() = true;
if x == 0 || x == 1 {
x
} else {
// `f` is `fib`
b(Box::new(f), x - 1) + f(x - 2)
}
});
fn b (c: Box<Fn(u64) -> u64>, n: u64) -> u64 {
c(n)
}
println!("{}", b(Box::new(fib), 10));
}
外部板条箱工具;
使用工具::前奏::*;
使用std::cell::RefCell;
fn main(){
设a=RefCell::new(false);
设fib=fix(移动| f,x |{
*a、 借用_mut()=真;
如果x==0 | | x==1{
x
}否则{
//'f'是'fib`
b(盒子:新的(f),x-1)+f(x-2)
}
});
fn b(c:Box u64>,n:u64)->u64{
c(n)
}
println!(“{}”,b(Box::new(fib),10));
}
错误[E0495]:由于需求冲突,无法推断适当的生存期
-->src/main.rs:14:24
|
14 | b(盒子:新的(f),x-1)+f(x-2)
| ^
|
注意:首先,生命周期不能超过8:19在身体上定义的匿名生命周期#2。。。
-->src/main.rs:8:19
|
8 |让fib=固定(移动| f,x |{
| ___________________^
9 | |*a.借用_mut()=真;
10 | |如果x==0 | | x==1{
11 | | x
... |
15 | | }
16 | | });
| |_____^
=注意:…因此表达式是可赋值的:
预期&dyn标准::操作::Fn(u64)->u64
已找到&dyn std::ops::Fn(u64)->u64
=注意:但是,生存期必须对静态生存期有效。。。
=注意:…因此表达式是可赋值的:
应为std::boxed::Box u64+‘静态)>
找到std::boxed::Box u64>
看起来您在这里混合了几个概念。首先,您必须了解以下各项之间的区别:
fn(A)->B
impl-Fn(A)->B
或T:Fn(A)->B
&dyn Fn(A)->B
框B>
Fn
的泛型类型,该类型是可调用的
数字3是对可调用对象的动态引用(dyn
关键字是可选的)
数字4是一个trait对象,它是一个实类型为erased的装箱可调用对象
现在看一下以下定义:
似乎对我有用。这就是你想要的吗?这对我也有用。但我发现我需要的东西比它还复杂。我不知道我是需要休息一下,还是继续问问题。我刚开始生锈,我很累。我想要的是:看起来你在混合
fn
,dyn-fn
,也许还有impl-fn
。我不熟悉工具
,但会胡闹,编译。我很快就会学会的,嗨,我刚在你帮我的时候改变了要点。请您再检查一下:在您的第一条评论中,我没有看到任何动态引用,fnb(c:impl-fn(u64)->u64,n:u64)
刚刚成功,为什么@周汉成: 啊,但是注释中的代码确实有一个动态引用。您看不到它,因为类型是由编译器推导出来的:lambda函数中的f
参数。如果您检查其类型,则它是&dyn-Fn()->\u
。这是意料之中的,因为这正是fix()
所需要的。
extern crate tool;
use tool::prelude::*;
use std::cell::RefCell;
fn main() {
let a = RefCell::new(false);
let fib = fix(move |f, x| {
*a.borrow_mut() = true;
if x == 0 || x == 1 {
x
} else {
// `f` is `fib`
b(Box::new(f), x - 1) + f(x - 2)
}
});
fn b (c: Box<Fn(u64) -> u64>, n: u64) -> u64 {
c(n)
}
println!("{}", b(Box::new(fib), 10));
}
pub fn fix<A, B, F>(f: F) -> impl Fn(A) -> B
where
F: Fn(&Fn(A) -> B, A) -> B,
fn main() {
fn wrap (wrap_fn: impl Fn(&dyn Fn(u64) -> u64, u64) -> u64) -> impl Fn(u64) -> u64 {
let a = RefCell::new(false);
let fib = fix(move |f, x| {
*a.borrow_mut() = true;
if x == 0 || x == 1 {
x
} else {
// `f` is `fib`
wrap_fn(f, x - 1) + wrap_fn(f, x - 2)
}
});
fib
}
fn b (c: &dyn Fn(u64) -> u64, n: u64) -> u64 {
c(n)
}
println!("{}", (wrap(b))(10));
}