rust 如何将闭包移到结构域?

fxnxkyjh  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(89)

我有一段不工作的rust代码:

use std::cmp::Ordering;

struct Sortable<T> {
    buffer: Vec<T>,
    compare: Box<dyn Fn(&T, &T) -> Ordering>,
}

impl<T> Sortable<T> {
    fn new(compare_func: impl Fn(&T, &T) -> Ordering) -> Sortable<T> {
        Sortable {
            buffer: Vec::new(),
            compare: Box::new(compare_func),
        }
    }

    fn sort(&mut self) {
        self.buffer.sort_by(&self.compare);
    }
}

字符串
编译器抛出此错误:

the parameter type `impl Fn(&T, &T) -> Ordering` may not live long enough


我认为参数compare_func将从调用者移动到函数new,然后移动到结构字段compare,因为函数声明中没有引用(&)。但不知何故,错误是关于生存期问题。我在这里做错了什么吗?或者有一些变通方法可以做到这一点?

u91tlkcl

u91tlkcl1#

在Rust中,当你在另一个类型的定义中有一个引用类型时,借用规则需要显式的生命周期注解来确保引用的正确性。当直接在结构中使用函数指针或闭包时,Rust需要知道对这些函数的引用在多长时间内有效以确保安全。这就是显式生命周期注解变得至关重要的地方。
另一种解决方案是传递生存期参数

use std::cmp::Ordering;

struct Sortable<'a, T> {
    buffer: Vec<T>,
    compare: Box<dyn Fn(&T, &T) -> Ordering + 'a>,
}

impl<'a, T> Sortable<'a, T> {
    fn new(compare_func: impl Fn(&T, &T) -> Ordering + 'a) -> Sortable<'a, T> {
        Sortable {
            buffer: Vec::new(),
            compare: Box::new(compare_func),
        }
    }

    fn sort(&mut self) {
        self.buffer.sort_by(&self.compare);
    }
}

字符串
寿命参数'a描述了Sortable结构体所持有的引用的寿命。'a寿命参数应用于compare字段,指示compare中存储的闭包的寿命至少与Sortable结构体本身一样长。

pgx2nnw8

pgx2nnw82#

这可以通过要求闭包具有静态生存期来解决。这反映了函数签名中结构体的生存期要求。

use std::cmp::Ordering;

struct Sortable<T> {
    buffer: Vec<T>,
    // Since a lifetime is not specified, this type is inferred to be
    // Box<dyn 'static + Fn(&T, &T) -> Ordering>
    compare: Box<dyn Fn(&T, &T) -> Ordering>,
}

impl<T> Sortable<T> {
    fn new(compare_func: impl Fn(&T, &T) -> Ordering + 'static) -> Sortable<T> {
        Sortable {
            buffer: Vec::new(),
            compare: Box::new(compare_func),
        }
    }

    fn sort(&mut self) {
        self.buffer.sort_by(&self.compare);
    }
}

字符串
Rust Playground的一个。

相关问题