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
?
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
?
Odpowiedzi:
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.
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 a String
, najbardziej wydajne jest ponowne użycie alokacji z String::from_utf8
:
fn main() {
let bytes = vec![0x41, 0x42, 0x43];
let s = String::from_utf8(bytes).expect("Found invalid UTF-8");
println!("{}", s);
}
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 potrzebujesz expect
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ładach from_utf8_lossy
. doc.rust-lang.org/std/string/…