Returning structure with generic arguments

I have a function that returns LazySortIteratorBy<T, F> but I'm not quite sure how to specify generic arguments for the return type in an example from https://docs.rs/crate/lazysort/0.2.1:

fn test(&self) -> ??? {
    let before: Vec<&str> = vec!["a", "cat", "sat", "on", "the", "mat"];
    before.iter().sorted_by(|a, b| {
        match a.len().cmp(&b.len()) {
            Equal => a.cmp(b),
            x => x
        }
    })
}

I'd like to understand:

  • how to return such type (in case of e.g. internal functions)
  • what is the best practice if this function was a public interface (e.g. wrap it in my own iterator to hide the implementation detail? define a type alias?)

you could just do

fn test(&self) -> impl Iterator<Item  = &str>
1 Like

Thank you @RustyYato that fits perfectly.

As a followup question, how does one go about specifying lifetimes when returning impl trait with borrowed values?

Let's say the Vec is passed into the function like:

fn test(before: &Vec<&str>) -> impl Iterator<Item = &&str> {
    before.iter().sorted_by(|a, b| {
        match a.len().cmp(&b.len()) {
            Equal => a.cmp(b),
            x => x
        }
    })
}

The compiler says that

... impl Iterator<Item = &&str>
...                      ^ expected lifetime parameter

help: this function's return type contains a borrowed value, but the signature does not say which one of `before`'s 2 lifetimes it is borrowed from

Does this work?

fn test<'vec, 'item>(before: &'vec Vec<&'item str>) -> impl 'vec + Iterator<Item = &'vec &'item str>

Basically, the iterator has comes from the Vec<_> and so each reference that the iterator yields also comes from the Vec<_> (why they have lifetime 'vec), but the strings could come from somewhere else, so they have their own lifetimes ('item).

Thanks a lot, that did work. Your explanation helped me, I didn't realise I needed to specify lifetimes for both && as &'vec &'item.

I don't think you need to specify all of the lifetimes, I did because I wasn't sure which ones were needed. You can remove some of the lifetime annotations to see which ones you actually need.

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