rust 由于生存期的原因,返回引用的闭包无法编译

vlju58qv  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(98)

我试图实现一个通用函数,除其他外,过滤非唯一的值从一个向量的一些任意条件。我使用itertools的unique_by方法,它接受一个闭包,在我的例子中,它返回一个对一些数据的引用来进行比较。

use itertools::Itertools;
use std::hash::Hash;

#[derive(Clone)]
struct Person {
    uints: Vec<usize>,
}

#[derive(Clone)]
struct Dog {
    ints: Vec<i8>,
}

fn filter_duplicates(population: &[Person]) -> Vec<Person> {
    population
        .iter()
        .unique_by(|x| &x.uints)
        .cloned()
        .collect::<Vec<_>>()
}

fn filter_duplicates_generic<T: Clone, V: Eq + Hash, F: Fn(&&T) -> V>(
    population: &[T],
    unique_representation: F,
) -> Vec<T> {
    population
        .iter()
        .unique_by(unique_representation)
        .cloned()
        .collect::<Vec<_>>()
}

fn main() {
    let people = vec![
        Person {
            uints: vec![0, 1, 2],
        },
        Person {
            uints: vec![0, 1, 2],
        },
        Person {
            uints: vec![3, 4, 5],
        },
    ];

    let dogs = vec![Dog { ints: vec![0] }];

    // works.
    filter_duplicates(&people);

    // fails not compile.
    filter_duplicates_generic(&people, |x| &x.uints);
    filter_duplicates_generic(&dogs, |x| &x.ints);
}

当直接在方法内部编写闭包时,一切都很完美,但是当从外部传递闭包时,我得到了一个编译错误:

lifetime may not live long enough
returning this value requires that `'1` must outlive `'2`
main.rs(45, 64): has type `&&'1 Person`
main.rs(45, 65): return type of closure is &'2 std::vec::Vec<usize>

我尝试指定生命周期,但未能以富有成效的方式这样做。为什么itertools可以接受这种类型的闭包到他们的方法“unique_by”,而我不能接受一个到我自己的函数“filter_duplicates_generic”?

sy5wg1nm

sy5wg1nm1#

由于&&,Rust不能自动将相同的生存期应用于函数签名中的所有引用。你必须手动操作。

fn filter_duplicates_generic<'a, T: Clone, V: Eq + Hash, F: Fn(&&'a T) -> V>(
    population: &'a [T],
    unique_representation: F,
) -> Vec<T> {

Playground

相关问题