function A
以function B
作为参数,function B
再次以function C
作为参数。我尝试如下语法,但这给了我一个错误:
fn a(b: impl Fn(impl Fn() -> ()) -> ()) -> () {
// ...
}
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`
由于某些原因,我不能使用&dyn
关键字:
fn a(b: impl Fn(&dyn Fn() -> ()) -> ()) -> () {
// ...
}
还有其他方法吗?
我不知道为什么嵌套impl Trait
会导致错误。
答案 0 :(得分:10)
嵌套的隐式特性不起作用,因为尚未指定或实现。另外,因为考虑到Rust的其他部分如何工作,它并不是很有用。
fn a(b: impl Fn(impl Fn() -> ()) -> ()) -> ()
可以使用完全通用语法编写为
fn a<B, C>(b: B) -> ()
where B: Fn(C) -> (),
C: Fn() -> ()
那是什么意思?这意味着B
是可调用对象,它接受其他可调用对象的参数。但是这里重要的是具体类型。具体来说,B
不会接受具有兼容签名的任何呼叫,而特别是C
。什么是C?好吧,这就是问题所在。如果您这样拨打a
:
a(|f| f());
然后C
是lambda参数f
的类型,但是该类型是未知的,因为不能单独从用法中推导出参数f
的类型。但是假设这不是问题,a
的主体将是什么样?
fn a<B, C>(b: B) -> ()
where B: Fn(C) -> (),
C: Fn() -> () {
b(|| ())
}
在这里,我们尝试调用b
传递lambda。但是lambda的类型是unnamed local lambda type
,而不是C
。由于C
是从外部传入的,因此它不能是a
本地的lambda类型。简而言之,除非您将C
作为a
的附加参数传递,否则a
不会传递给{{1} }。
您显然希望b
不是一个可以用某些B
调用但可以用 any C
调用的函数对象。您希望它是一个多态函数对象。 Rust不支持编译时多态函数对象(Haskell中的等效对象为C
或类似的对象)。它仅支持运行时多态函数对象。
这就是forall a. a -> IO ()
的工作。现在,您已经说过不能使用dyn
,因为您要将函数对象传递给另一个线程。因此,请改用&dyn
:
Box<dyn>