Vec<u8> -> String

I'm new to Rust and have been trying out the code.

I have a Vec that I want to convert to a String

The few solutions I have found do not compile. It seems conversion should be simple. What am I misunderstanding?.

1 Like

You can use String::from_utf8 to create a String from a Vec<u8> in a way that avoids creating allocations. It will return an error if your bytes contain invalid utf8 sequences.

Playground

fn main() {
    let bytes: Vec<_> = b"here's a byte string".to_vec();

    let string = String::from_utf8(bytes).expect("Our bytes should be valid utf8");

    println!("{string}")
}
4 Likes

I notice the vec type is not u8 but taken from your initializing byte string. My problem is u8 which panics when you are using from_utf8

This code snippet initializes a Vec<u8> and converts it to a String using String::from_utf8. Remember that this method returns a Result<String, FromUtf8Error>, so if the bytes are not valid UTF-8, it will return an error. If you expect that your data might contain invalid UTF-8 sequences, you should handle the error appropriately instead of using expect(). For example, you can use pattern matching:

fn main() {
    let bytes: Vec<_> = b"here's a byte string".to_vec();

    match String::from_utf8(bytes) {
        Ok(string) => println!("{}", string),
        Err(e) => println!("Error: {}", e),
    }
}

This code will print the error message if the conversion fails, instead of panicking.

That still doesn't fix your problem though. I'd look at the raw data and see whether it is actually a string (e.g. by saving to a file and opening it in an editor or using a hexdump tool like xxd). The data you are trying to read might actually be binary and not text.

Alternatively, there is String::from_utf8_lossy() which will replace invalid UTF-8 characters with the UTF-8 replacement character (�). This can help if something happened to make just a small part of the text corrupted (unlikely given how reliable disks are today and TCP's guarantees).

If you are sure the Vec<u8> contains text, it might be in an encoding other than UTF-8. Rust strings only work with UTF-8 text, so you'll need to reach for something like the encoding crate to handle other text encodings.

4 Likes

Thanks for clearing up my misunderstanding, Obviously I need to refine my code based on your comments.

or you can use std::str::from_utf_8,
the advantage is that it returns &str,does not clone data.
play_ground:Rust Playground

String::from_utf8() doesn't clone the data, either.

3 Likes

thanks for the clarification , I didn't know

It would be correct to say that std::str::from_utf_8 just borrows data,not how String::from_utf8()

Yes, they do different things w.r.t. ownership, but neither of them clones. str::from_utf8() avoids cloning by borrowing, while String::from_utf8() avoids cloning by moving.

3 Likes

std::str::from_utf8 both takes (&[u8]) and returns (Result<&str, _>) borrowed data. If you have a v: Vec<u8> pass it &v, that will coerce to a &[u8] and be a borrow of your Vec<u8>. If you only have a borrow or if you don't want to lose ownership of a Vec you have, use this one. If you need a String and not a (borrowed) &str, subsequently use .to_string() on the &str. [1]

String::from_utf8 both takes (Vec<u8>) and returns (Result<String, _>) owned data. If you have a Vec<u8> and don't mind losing ownership of it, use this one. [2]


  1. It will only do the UTF8 check once and this way you won't clone unless you have valid UTF8. ↩︎

  2. It will only do the UTF8 check once and this way you won't clone at all. ↩︎

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.