Partition a vector with a non-copy type

I am a little confused by Rusts behaviour with partition.

The documentation is perfectly clear, but when trying it out like so:

fn main() {
    let a = ["1".to_string(), "10".to_string(),
             "2".to_string(), "20".to_string()
    ];

    let (one, two): (Vec<String>, Vec<String>) = a
        .iter()
        .partition(|n| n.len() % 2 == 0);
}

I find that partition requires its items to be Copy. The rustdoc
example uses int, so the problem never shows up.

I am trying to split a Vec; some elements will match a predicate
which I want to do something with, but they then have to be removed
from the Vec. partition seems to be just the thing here, but my
type implements clone not copy (it's an enum with Rc's
underneath).

What am I doing wrong? And why is partition copy?

The partition function does not require Copy, instead it's because if you have an iterator of &T for some T, you can collect it into a collection of type T if and only if T is Copy. Since you explicitly said the item should be String and not &String, it tries to use this impl, but fails.

To fix this, either specify the correct type:

fn main() {
    let a = ["1".to_string(), "10".to_string(),
             "2".to_string(), "20".to_string()
    ];

    let (one, two): (Vec<&String>, Vec<&String>) = a
        .iter()
        .partition(|n| n.len() % 2 == 0);
}

You can also use into_iter instead which takes ownership, but it doesn't work for raw arrays, so you'd have to create the iterator from a vector or something.

1 Like

Oh, yeah. I started off with into_iter because I thought it would be needed, then removed it after seeing iter in the documentation. Never read the documentation!

Thanks

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.