2016-12-16 16 views
11

За Steve Klabnik's writeup in the pre-Rust 1.0 documentation on the difference between String and &str, в Rust вы должны использовать &str, если вам действительно не требуется владение над String. Точно так же рекомендуется использовать ссылки на срезы (&[]) вместо Vec с, если вам не требуется владение над Vec.Convert Vec <String> в ломтик & str в ржавчине?

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

ответ

13

Вы можете создать функцию, которая принимает как &[String] и &[&str] с помощью 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); 
} 
+1

Я думаю, что это ответ, который ищет OP, поскольку он позволяет использовать срез без лишнего выделения. Этот подход еще более полезен при принятии фрагмента 'AsRef ' - вы хотите, чтобы функция принимала все '& [& str]', '& [String]', '& [Path]' и '& [PathBuf ] ', не выделяя новую память. – user4815162342

4

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

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

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

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

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

+0

Спасибо, Матье. Для моего случая прямо сейчас, я думаю, я поеду с '& [String]', так как я предполагаю, что выделение нового 'Vec <&str>' несет дополнительную работу. –

+1

@DonRowe: Это требует дополнительного распределения (O (1), но потенциально дорогого) + преобразования (O (n)). –