Question about function argument convention regarding &Vec<String> vs &[&str]

The core there is this line:

let test: String = thing.to_string();

If that’s what you’re doing with the elements, then perhaps you want

fn test(something: &[impl ToString]) {
    for thing in something {
        let test: String = thing.to_string();
        println!("{:?}", test);
    }
}

Which allows even more things, like

test(&[1,2,3]);

But you were probably looking instead for something like this:

fn test(something: &[impl AsRef<str>]) {
    for thing in something {
        println!("{:?}", thing.as_ref());
    }
}
1 Like

Ok, after your help (and chapter 12) I think I found a clear way to do this. Not sure how efficient this is, but it seems widely compatible

fn test(something_raw: &[impl AsRef<str>]){
    let something: Vec<&str> = something_raw.iter()
        .map(
            |thing| {
                thing.as_ref()
            }
        ).collect();
    println!("{:?}",something);
}

Playground link

I’m trying to generalize this but running into some lifetime issues. I’m trying to say that for both the input and the output, the outer vec should have a lifetime of 'a and the contents should have a lifetime of 'b

but the &something_raw.iter() is giving the error

cannot infer an appropriate lifetime for autoref due to conflicting requirements

fn vec_as_borrowed
  <'a, 'b, T: 'b>
  (something_raw: &'a [impl AsRef<T>]) // I think there's supposed to be a 'b here but can't get it to take one
  -> &'a Vec<&'b T> {
    let something: &'a Vec<&'b T> = &something_raw.iter()
        .map(
            |thing| {
                thing.as_ref()
            }
        ).collect();
        something
}

Playground

// I think there's supposed to be a 'b here but can't get it to take one

The error you are seeing right now can be fixed by adding the requirement 'a: 'b.

However, your function has a much more significant issue, which the compiler will reveal to you after you fix a couple more errors. You are trying to return a reference to a temporary living on the stack. This is impossible. You will almost certainly need to return a Vec<&'b T> instead.

The only way that a function can conceivably return an &_ is if it is stored in one of the arguments to the function, or in a static variable.

1 Like

I thought this might be the case, though I was hoping because we receive a borrowed array that we might be able to tie the lifetime of the Vec to the lifetime of that array since they’re functionally twins