2016-12-16 59 views
11

Na Steve Klabnik's writeup in the pre-Rust 1.0 documentation on the difference between String and &str, w Rust powinieneś używać &str, chyba że naprawdę potrzebujesz własności ponad String. Podobnie zaleca się używanie odniesień do plasterków (&[]) zamiast Vec s, chyba że naprawdę potrzebujesz własności nad Vec.Konwertuj Vec <String> na plasterka & str w Rust?

mam Vec<String> i chcę napisać funkcję, która używa tej sekwencji łańcuchów i nie wymaga posiadania nad Vec lub String przypadkach należy wziąć &[&str] że funkcja? Jeśli tak, jaki jest najlepszy sposób odniesienia się do Vec<String> do &[&str]? A może to przesada?

Odpowiedz

13

Można utworzyć funkcję, która akceptuje zarówno &[String] i &[&str] pomocą 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

Myślę, że jest to odpowiedź, której szukał OP, ponieważ pozwala na użycie plasterka bez niepotrzebnego przydziału. Takie podejście jest jeszcze bardziej przydatne przy akceptowaniu plasterka 'AsRef ' - chcesz, aby funkcja akceptowała wszystkie '& [& str]', '& [String]', '& [Path]' i '& [PathBuf ], bez przydzielania nowej pamięci. – user4815162342

4

Jest to praktycznie niemożliwe bez przydziału pamięci .

Chodzi o to, że przejście od String do &str nie polega wyłącznie na oglądaniu bitów w innym świetle; String i &str mają inny układ pamięci, a zatem przechodzenie od jednego do drugiego wymaga utworzenia nowego obiektu. To samo odnosi się do Vec i &[]

Dlatego, podczas gdy można przejść od Vec<T> do &[T], a tym samym z Vec<String> do &[String], nie można bezpośrednio przejść z Vec<String> do &[&str]:

  • zaakceptować używać &[String]
  • lub przydzielić nowy Vec<&str>, odwołując się do pierwszego Vec, i przekształcić , który w

Konwersja wymagana jest niemożliwe, jednak przy użyciu rodzajowych i AsRef<str> związane, jak pokazano na @aSpex „s odpowiedzi otrzymasz deklarację funkcji nieco bardziej rozwlekły elastyczności pan prosi.

+0

Dzięki Matthieu. Dla mojej sprawy teraz, myślę, że pójdę z '& [String]', ponieważ wyobrażam sobie, że przydzielenie nowego 'Vec <&str>' powoduje dodatkową pracę. –

+1

@DonRowe: To powoduje dodatkową alokację (O (1), ale potencjalnie kosztowna) + konwersja (O (n)). –