在 Rust 中,我创建了一个 impl 返回类型,我可以将其作为参数传递。但是我没有找到将其存储在结构中的方法?



我已经将其精简并更改为通道,这样它可能更有意义。我想存储一个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";不是类型它或多或少是未命名类型(在返回值位置(或类型参数(在参数位置(的语法糖。

  1. fn make_test<T>(sender: Sender<T>) -> impl Fn()->bool {
    

    在返回位置;有一个特定的具体类型,但我没有把它写出来,它可能会改变,但它肯定会实现Fn() -> bool"。需要返回裸闭包,否则它们的类型不可命名。(如果可以编写闭包的类型,则必须指定所有闭包值的类型。(

  2. 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参数。

但是,如果你想避免dynamic调度的成本,你最好用一个显式定义的结构和方法来替换你的闭包——或者,如果适用的话(我还没有研究过你实际想做什么(,只需要让MyParker成为那个结构,这样它就有一个类型为Sender<T>的字段。

最新更新