Convert Vec into a slice of &str in Rust?

前端 未结 2 710
深忆病人
深忆病人 2020-11-30 07:21

Per Steve Klabnik\'s writeup in the pre-Rust 1.0 documentation on the difference between String and &str, in Rust you should use &str unless you really

相关标签:
2条回答
  • 2020-11-30 07:50

    You can create a function that accepts both &[String] and &[&str] using the AsRef trait:

    fn test<T: AsRef<str>>(inp: &[T]) {
        for x in inp { print!("{} ", x.as_ref()) }
        println!("");
    }
    
    fn main() {
        let vref = vec!["Hello", "world!"];
        let vown = vec!["May the Force".to_owned(), "be with you.".to_owned()];
        test(&vref);
        test(&vown);
    }
    
    0 讨论(0)
  • 2020-11-30 07:53

    This is actually impossible without memory allocation1.

    Going from String to &str is not just viewing the bits in a different light; String and &str have a different memory layout, and thus going from one to the other requires creating a new object. The same applies to Vec and &[]

    Therefore, whilst you can go from Vec<T> to &[T], and thus from Vec<String> to &[String], you cannot directly go from Vec<String> to &[&str]. Your choices are:

    • either accept &[String]
    • allocate a new Vec<&str> referencing the first Vec, and convert that into a &[&str]

    As an example of the allocation:

    fn usage(_: &[&str]) {}
    
    fn main() {
        let owned = vec![String::new()];
    
        let half_owned: Vec<_> = owned.iter().map(String::as_str).collect();
    
        usage(&half_owned);
    }
    

    1 The conversion required is impossible, however using generics and the AsRef<str> bound as shown in @aSpex's answer you get a slightly more verbose function declaration with the flexibility you were asking for.

    0 讨论(0)
提交回复
热议问题