Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a function that takes both owned and non-owned string collections?

Tags:

I'm having trouble writing a function that takes a collection of strings as parameter. My function looks like this:

type StrList<'a> = Vec<&'a str>;

fn my_func(list: &StrList) {
    for s in list {
        println!("{}", s);
    }
}

All goes well if I pass a Vec<&'a str> to the function, as expected. However, if I pass a Vec<String> the compiler complains:

error[E0308]: mismatched types
  --> src/main.rs:13:13
   |
13 |     my_func(&v2);
   |             ^^^ expected &str, found struct `std::string::String`
   |
   = note: expected type `&std::vec::Vec<&str>`
   = note:    found type `&std::vec::Vec<std::string::String>`

This is the main used:

fn main() {
    let v1 = vec!["a", "b"];
    let v2 = vec!["a".to_owned(), "b".to_owned()];
    my_func(&v1);
    my_func(&v2);
}

My function is not able to take vectors of owned strings. Conversely, if I change the StrList type into:

type StrList = Vec<String>;

The first call fails, and the second works.

A possible solution is to produce a Vec<&'a str> from v2 in this way:

let v2_1 : Vec<_> = v2.iter().map(|s| s.as_ref()).collect();

But it seems very odd to me. my_func should not care about the ownership of the strings.

What kind of signature should I use for my_func to support both vectors of owned strings and string references?