我已经将其精简并更改为通道,这样它可能更有意义。我想存储一个impl
,它是一个谓词函数,在我的Struct
中,代码如下。。。
从一个简单的函数开始,该函数返回一个impl
用于测试某些内容。
fn make_test<T>(sender: Sender<T>) -> impl Fn()->bool {
let closure = move|| {sender.is_full()};
closure
}
struct MyStruct <T> {
sender: Sender<T>,
parker: Arc<Mutex<MyParker>>,
}
impl<T> MyStruct<T> {
fn something(&self) {
在这里,我们创建它并将其作为parameter
传递。
let test = make_test(self.sender.clone());
&self.parker.lock().unwrap().parked(test);
}
}
struct MyParker {
test: impl Fn()->bool,
}
impl MyParker {
fn parked(&mut self, test: impl Fn()->bool) {
parameter
被接受为test
,没有问题。但是,我如何在Struct
中声明它,以便稍后保存它?
self.test = test;
}
}
正如我目前所声明的,它抛出了一个编译器错误:错误[E0562]:在函数和固有方法返回类型之外不允许impl Trait
我希望这是我做错了什么的结果,而不是你不能在Struct中存储impl
。我试过了:Arc<>
,Box<>
,都没有用。
"一个CCD_ 12";不是类型它或多或少是未命名类型(在返回值位置(或类型参数(在参数位置(的语法糖。
fn make_test<T>(sender: Sender<T>) -> impl Fn()->bool {
在返回位置;有一个特定的具体类型,但我没有把它写出来,它可能会改变,但它肯定会实现
Fn() -> bool
"。需要返回裸闭包,否则它们的类型不可命名。(如果可以编写闭包的类型,则必须指定所有闭包值的类型。(fn parked(&mut self, test: impl Fn()->bool) {
这是的纯糖
fn parked<T: impl Fn()->bool>(&mut self, test: T) {
也就是说,
parked
是一个通用函数。
因此,不能仅具有类型为impl ...
的结构字段,因为它不是具体类型。当你有一个以上的类型时,你可以做的事情和其他任何时候都一样:你可以写一个带有类型参数的结构
struct MyParker<F: Fn() -> bool + 'static> {
test: F,
}
但这不起作用,因为您不能将事物约束到未知的闭包类型,或者您可以编写一个包含dyn
值的结构。
struct MyParker {
test: Box<dyn Fn() -> bool + 'static>,
}
impl MyParker {
fn parked(&mut self, test: impl Fn() -> bool + 'static) {
self.test = Box::new(test);
}
}
请注意,为了存储Fn
,我们需要提供一个生存期绑定。我在这里把它写成了'static
,但您也可以使用一个lifetime参数。
但是,如果你想避免dyn
amic调度的成本,你最好用一个显式定义的结构和方法来替换你的闭包——或者,如果适用的话(我还没有研究过你实际想做什么(,只需要让MyParker
成为那个结构,这样它就有一个类型为Sender<T>
的字段。