Bir Bayt Vektörünü (u8) dizeye nasıl dönüştürebilirim


99

Rust'ta basit bir TCP / IP istemcisi yazmaya çalışıyorum ve sunucudan aldığım arabelleği yazdırmam gerekiyor.

A Vec<u8>(veya a &[u8]) 'yı a'ya nasıl dönüştürürüm String?

Yanıtlar:


104

Bir bayt dilimini bir dize dilimine dönüştürmek için (UTF-8 kodlaması varsayılarak):

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

Dönüştürme yerinde ve bir tahsis gerektirmiyor. Bir oluşturabilir Stringgerekirse çağırarak dize dilim gelen .to_owned()dize dilim ( diğer seçenekler mevcuttur ).

Dönüştürme işlevi için kitaplık referansı:


Bunun mümkün olduğunu eklemek isteyebilirsiniz çünkü Vec dilimlere
baskı yapıyor

Örnek kod aslında bir Vector kullanmasa da :-)
Andrew Mackenzie

from_utf8Tahsis etmediği doğru olsa da , utf-8 doğruluğunu onaylamak için verileri taraması gerektiğinden bahsetmeye değer olabilir. Yani bu bir O (1) operasyonu değil (ilk başta düşünebilirsiniz)
Zargony

69

Tercih ederim String::from_utf8_lossy:

fn main() {
    let buf = &[0x41u8, 0x41u8, 0x42u8];
    let s = String::from_utf8_lossy(buf);
    println!("result: {}", s);
}

Geçersiz UTF-8 baytlarını 'ye çevirir ve bu nedenle herhangi bir hata işlemeye gerek yoktur. Buna ihtiyacın olmadığı zamanlar için iyi ve benim de pek ihtiyacım yok. Aslında bundan bir alırsınız String. Sunucudan aldığınız şeyi yazdırmayı biraz daha kolaylaştırmalıdır.

Bazen into_owned(), yazma sırasında klonlandığı için bu yöntemi kullanmanız gerekebilir .


4
into_owned()Öneriniz için çok teşekkürler ! Tam olarak aradığım şeydi (bu, Stringörneğin bir yöntemden dönüş değeri olarak geri dönebileceğiniz bir uygun hale getirir ).
Başına Lundberg

49

Aslında bir bayt ( Vec<u8>) vektörünüz varsa ve a'ya dönüştürmek istiyorsanız String, en verimli olan ayırmayı aşağıdakilerle yeniden kullanmaktır String::from_utf8:

fn main() {
    let bytes = vec![0x41, 0x42, 0x43];
    let s = String::from_utf8(bytes).expect("Found invalid UTF-8");
    println!("{}", s);
}

2
Teşekkürler! Diğer iki cevap soruyu neden görmezden geldi?
Jehan

1
@Jehan, çünkü insanlar genellikle soru sormada iyi değiller, özellikle de bir dilde yeni olduklarında. Rust bir dizi , bir dilim ve a arasında bir ayrım yapar Vec, ancak yeni gelenler farklılıkları bilmiyor. Yine de yararlı olduğunu kanıtlayan tüm soruları ve yanıtları olumlu oyladığınızdan emin olun.
Shepmaster

@Bjorn Tipling tarafından belirtildiği gibi String::from_utf8_lossybunun yerine burada kullanabileceğinizi unutmayın , o zaman beklenen aramaya ihtiyacınız yoktur.
James Ray

2
Düzenleme: @Bjorn Tipling tarafından belirtildiği gibi String::from_utf8_lossy, burada bunun yerine kullanabileceğinizi düşündüğünüzü unutmayın , o zaman expectçağrıya ihtiyacınız yoktur , ancak bunun girdisi bir bayt ( &'a [u8]) dilimidir . OTOH, ayrıca var from_utf8_unchecked. "Bayt diliminin geçerli UTF-8 olduğundan eminseniz ve dönüşümün ek yüküne maruz kalmak istemiyorsanız, bu işlevin [ from_utf8_lossy], from_utf8_uncheckedaynı davranışa sahip olan ancak kontrolleri atlayan güvenli olmayan bir sürümü vardır. "
James Ray

&vec_of_bytesÖrneklerinde listelendiği gibi, bir bayt dilimine geri dönüştürmek için kullanabileceğinizi unutmayın from_utf8_lossy. doc.rust-lang.org/std/string/…
James Ray
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.