How to set lifetime of slice::sort_by_key to make it support reference value?

⚓ Rust    📅 2025-06-30    👤 surdeus    👁️ 4      

surdeus

Warning

This post was published 38 days ago. The information described in this article may have changed.

Hi , I try to sort a slice by a string field, Is it possible to use sort by key without memery allocating of String?

fn main() {
    let mut values: Vec<V1> = vec![
        // some test values
    ];

    // this work
    values.sort_by(|left, right| left.s.cmp(&right.s));

    // compile error: lifetime may not live long enough
    values.sort_by_key(|v| &v.s);

    // compile error: lifetime may not live long enough
    my_sort_by_key(&mut values, |v| &v.s);

    println!("{values:?}")
}

fn my_sort_by_key<K, T, F>(vec: &mut Vec<T>, mut f: F)
where
    K: Ord,
    for<'a> F: FnMut(&'a T) -> K + 'a,
{
    vec.sort_by(|left, right| f(left).cmp(&f(right)))
}

#[derive(Debug)]
struct V1 {
    n: i32,
    s: String,
}

It works if I use &K instead of K, but still can not support tuple with &str in it.

fn main() {
    let mut values: Vec<V1> = vec![
        // some test values
    ];

    // this work
    my_sort_by_key(&mut values, |v| &v.s);

    // this doesn't work
    my_sort_by_key(&mut values, |v| (&v.s, v.n));

    println!("{values:?}")
}

fn my_sort_by_key<K, T, F>(vec: &mut Vec<T>, mut f: F)
where
    K: Ord,
    // change return value from K + 'a to &'a K 
    for<'a> F: FnMut(&'a T) -> &'a K,
{
    vec.sort_by(|left, right| f(left).cmp(&f(right)))
}

#[derive(Debug)]
struct V1 {
    n: i32,
    s: String,
}

1 post - 1 participant

Read full topic

🏷️ rust_feed