Sized is not implemented for the type Fn

前端 未结 1 415
一整个雨季
一整个雨季 2020-12-03 17:32

I want to build a function that splits a list into two: one list that contains the elements of the original list that satisfy a certain predicate, and another that contains

相关标签:
1条回答
  • 2020-12-03 18:15

    You should read the official Rust book, especially the chapter on closures. Your function declaration is incorrect; you are specifying that f has a bare trait type, which is impossible; that's exactly what the error about Sized is about. You should use a generic type parameter instead:

    fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>)
    where
        F: for<'a> Fn(&'a T) -> bool,
    

    I have also changed the type of a from &Vec<T> to &[T]; there is no situation in which you would prefer the former to the latter. &Vec<T> is automatically coerced to &[T] when necessary. See Why is it discouraged to accept a reference to a String (&String) or Vec (&Vec) as a function argument?

    The second error is closely tied to the mistake in the function declaration; your original function declaration specified a bare trait type, but closures do not have this type, they just implement the function trait.

    The final program looks like this:

    fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>)
    where
        F: Fn(&T) -> bool,
    {
        let mut i: Vec<T> = vec![];
        let mut e: Vec<T> = vec![];
        for u in a.iter().cloned() {
            if f(&u) {
                i.push(u);
            } else {
                e.push(u);
            }
        }
    
        return (i, e);
    }
    
    fn main() {
        let v = vec![10, 40, 30, 20, 60, 50];
        println!("{:?}", split_filter(&v, |&a| a % 3 == 0));
    }
    

    Try it on the playground.

    0 讨论(0)
提交回复
热议问题