Преобразовать Vec в кусок &str в Rust?

Per запись Стива Клабника в документации pre-Rust 1.0 о разнице между String и &str, в Rust, вы должны использовать &str Если вам действительно не нужно иметь право собственности на String. Аналогично, рекомендуется использовать ссылки на срезы (&[]) вместо VecS Если вам действительно не нужно владение над Vec.

у меня есть Vec<String> и я хочу написать функцию, которая использует эту последовательность строк и это не нужно владение над Vec или String экземпляры, если эта функция принимает &[&str]? Если да, то каков наилучший способ ссылаться на Vec<String> на &[&str]? Или это принуждение излишне?

2 ответов


вы можете создать функцию, которая принимает как &[String] и &[&str] С помощью AsRef признак:

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);
}

это фактически невозможно без выделения памяти1.

дело в том, что едет из String до &str - это не просто просмотр битов в ином свете; String и &str имеют другой макет памяти, и, таким образом, переход от одного к другому требует создания нового объекта. То же самое относится к Vec и &[]

поэтому, пока вы можете пойти от Vec<T> to &[T], и, таким образом, с Vec<String> to &[String], вы не можете напрямую перейти от Vec<String> to &[&str]:

  • либо принять к использованию &[String]
  • или выделить новый Vec<&str> ссылка на первый Vec, и преобразовать это на &[&str]

1требуемое преобразование невозможно, однако с использованием дженериков и AsRef<str> связаны, как показано в @ "аспекс"ответ вы получаете немного более подробное объявление функции с гибкостью, которую вы просили.