Próbuję napisać prostego klienta TCP / IP w Rust i muszę wydrukować bufor, który otrzymałem z serwera.
Jak przekonwertować a Vec<u8>
(lub a &[u8]
) na a String
?
Aby przekonwertować wycinek bajtów na kawałek ciągu (zakładając kodowanie UTF-8):
use std::str;
//
// pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error>
//
// Assuming buf: &[u8]
//
fn main() {
let buf = &[0x41u8, 0x41u8, 0x42u8];
let s = match str::from_utf8(buf) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
println!("result: {}", s);
}
Konwersja odbywa się na miejscu i nie wymaga alokacji. Jeśli to konieczne, możesz utworzyć String
kawałek struny, wywołując .to_owned()
ten kawałek ( dostępne są inne opcje ).
Odniesienie do biblioteki dla funkcji konwersji:
from_utf8
nie alokuje, warto wspomnieć, że musi skanować dane, aby sprawdzić poprawność utf-8. Więc to nie jest operacja O (1) (o czym można by pomyśleć na początku)Wolę
String::from_utf8_lossy
:fn main() { let buf = &[0x41u8, 0x41u8, 0x42u8]; let s = String::from_utf8_lossy(buf); println!("result: {}", s); }
Zamienia nieprawidłowe bajty UTF-8 na , więc nie jest wymagana obsługa błędów. Jest dobry, gdy tego nie potrzebujesz, a ja prawie tego nie potrzebuję. Właściwie to dostajesz
String
z tego. Powinno to ułatwić drukowanie tego, co otrzymujesz z serwera.Czasami może być konieczne użycie
into_owned()
metody, ponieważ jest ona klonowana podczas zapisu.źródło
into_owned()
sugestię! Dokładnie tego szukałem (to sprawia, że stało się to właściwe,String
które możesz na przykład zwrócić jako wartość zwracaną z metody).Jeśli faktycznie masz wektor bajtów (
Vec<u8>
) i chcesz przekonwertować go na aString
, najbardziej wydajne jest ponowne użycie alokacji zString::from_utf8
:fn main() { let bytes = vec![0x41, 0x42, 0x43]; let s = String::from_utf8(bytes).expect("Found invalid UTF-8"); println!("{}", s); }
źródło
Vec
, ale nowicjusze nie znają różnic. Pamiętaj jednak, aby zagłosować za wszystkimi pytaniami i odpowiedziami, które okażą się przydatne.String::from_utf8_lossy
zamiast tego tutaj, wtedy nie potrzebujesz połączenia oczekującego.String::from_utf8_lossy
zamiast tego tutaj, wtedy nie potrzebujeszexpect
wywołania, ale wejście do tego jest kawałkiem bytess (&'a [u8]
). OTOH, jest teżfrom_utf8_unchecked
. „Jeżeli jesteś pewien, że kawałek jest ważny bajt UTF-8, a ty nie chcesz ponosić napowietrznej konwersji, jest niebezpieczna wersja tej funkcji [from_utf8_lossy]
,from_utf8_unchecked
, który ma ten sam problem, ale pomijają sprawdzenie. "&vec_of_bytes
do konwersji z powrotem na wycinek bajtów, jak wymieniono w przykładachfrom_utf8_lossy
. doc.rust-lang.org/std/string/…