function A这需要function B作为参数,再function B取function C作为参数.我尝试下面的语法,但这给了我一个错误:
fn a(b: impl Fn(impl Fn() -> ()) -> ()) -> () {
// ...
}
Run Code Online (Sandbox Code Playgroud)
error[E0666]: nested `impl Trait` is not allowed
--> src/main.rs:2:21
|
2 | fn a(b: impl Fn(impl Fn() -> ()) -> ()) -> () {
| --------^^^^^^^^^^^^^^^-------
| | |
| | nested `impl Trait` here
| outer `impl Trait`
Run Code Online (Sandbox Code Playgroud)
出于某种原因,我不能使用&dyn关键字:
fn a(b: impl Fn(&dyn Fn() -> ()) -> ()) -> () {
// ...
}
Run Code Online (Sandbox Code Playgroud)
有没有其他方法可以做到这一点?
我不知道嵌套impl Trait导致错误的原因.
Seb*_*edl 10
嵌套的impl Trait不起作用,因为尚未指定或实现它.另外,因为如果Rust的其他部分如何工作,它不是很有用.
fn a(b: impl Fn(impl Fn() -> ()) -> ()) -> () 可以使用完整的通用语法编写
fn a<B, C>(b: B) -> ()
where B: Fn(C) -> (),
C: Fn() -> ()
Run Code Online (Sandbox Code Playgroud)
那是什么意思呢?这意味着B可调用的东西可以调用其他可调用的东西.但重要的是具体类型.具体来说,B不使用兼容签名的任何可调用,但具体是a C.什么是C?嗯,这就是问题所在.如果你这样打电话a:
a(|f| f());
Run Code Online (Sandbox Code Playgroud)
那么C是lambda参数的f类型,但该类型是未知的,因为参数f的类型不能仅从使用中推断出来.但是假设这不是问题,a看起来像什么样的身体?
fn a<B, C>(b: B) -> ()
where B: Fn(C) -> (),
C: Fn() -> () {
b(|| ())
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们尝试调用b传递lambda.但lambda的类型unnamed local lambda type不是C.由于C从外部传入,它不能是lambda本地的类型a.简单地说,除非你在一传C作为一个额外的参数a,也没有什么是a有,它可以传递给b.
你显然想要的是B不是一个可以用某些东西调用的函数对象C,而是任何 函数对象C.您希望它是一个多态函数对象.Rust不支持编译时多态函数对象(Haskell中的等价物将是forall a. a -> IO ()或类似的).它仅支持运行时多态函数对象.
这是工作的dyn.现在你已经说过你不能使用了&dyn,因为你想将函数对象传递给另一个线程.所以相反,使用Box<dyn>:
fn a(b: impl Fn(Box<dyn Fn() -> ()>) -> ()) -> () {
b(Box::new(|| println!("Hello")))
}
fn main() {
a(move |f| { f(); f(); });
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |