snippetrustCritical
How do I convert between String, &str, Vec<u8> and &[u8]?
Viewed 0 times
howandbetweenstrconvertvecstring
Problem
A new Rustacean like me struggles with juggling these types:
In time, I hope to have an epiphany and suddenly get why some library calls use one or the other. Until then, I need help to map out each idiomatic transition.
Given these types:
I think I have figured these out, but are they idiomatic?
Ultimately I want a complete table of transitions for these types:
String, &str, Vec, &[u8].In time, I hope to have an epiphany and suddenly get why some library calls use one or the other. Until then, I need help to map out each idiomatic transition.
Given these types:
let st: &str = ...;
let s: String = ...;
let u: &[u8] = ...;
let v: Vec = ...;I think I have figured these out, but are they idiomatic?
&str -> String String::from(st)
&str -> &[u8] st.as_bytes()
String -> &str s.as_str()
&[u8] -> &str str::from_utf8(u)
Vec -> String String::from_utf8(v)
Ultimately I want a complete table of transitions for these types:
&str -> String
&str -> &[u8]
&str -> Vec
String -> &str
String -> &[u8]
String -> Vec
&[u8] -> &str
&[u8] -> String
&[u8] -> Vec
Vec -> &str
Vec -> String
Vec -> &[u8]
Solution
From
From
From
From
Coercion is available whenever the target is not generic but explicitly typed as
tl;dr
&str&str -> Stringhas many equally valid methods:String::from(st),st.to_string(),st.to_owned().
- But I suggest you stick with one of them within a single project. The major advantage of
String::fromis that you can use it as an argument to amapmethod. So instead ofx.map(|s| String::from(s))you can often usex.map(String::from).
&str->&[u8]is done byst.as_bytes()
&str->Vecis a combination of&str -> &[u8] -> Vec, i.e.st.as_bytes().to_vec()orst.as_bytes().to_owned()
From
StringString -> &strshould just be&swhere coercion is available ors.as_str()where it is not.
String -> &[u8]is the same as&str -> &[u8]:s.as_bytes()
String -> Vechas a custom method:s.into_bytes()
From
&[u8]&[u8] -> Vecis done byu.to_owned()oru.to_vec(). They do the same thing, butto_vechas the slight advantage of being unambiguous about the type it returns.
&[u8] -> &strdoesn't actually exist, that would be&[u8] -> Result, provided viastr::from_utf8(u)
str::from_utf8(u).unwrap()works, but you should prefer better error handling (see Error handling - The Result type).
&[u8] -> Stringis the combination of&[u8] -> Result -> Result
String::from_utf8(u).unwrap()works, but prefer better error handling (see Error handling - The Result type and alsoResult::map.
From
VecVec -> &[u8]should be just&vwhere coercion is available, oras_slicewhere it's not.
Vec -> &stris the same asVec -> &[u8] -> Resulti.e.str::from_utf8(&v)
str::from_utf8(&v).unwrap()works, but prefer better error handling (see Error handling - The Result type)
Vec -> Stringdoesn't actually exist, that would beVec -> ResultviaString::from_utf8(v)
String::from_utf8(v).unwrap()works, but prefer better error handling (see Error handling - The Result type).
Coercion is available whenever the target is not generic but explicitly typed as
&str or &[u8], respectively. The Rustonomicon has a chapter on coercions with more details about coercion sites.tl;dr
&str -> String | String::from(s) or s.to_string() or s.to_owned()
&str -> &[u8] | s.as_bytes()
&str -> Vec | s.as_bytes().to_vec() or s.as_bytes().to_owned()
String -> &str | &s if possible* else s.as_str()
String -> &[u8] | s.as_bytes()
String -> Vec | s.into_bytes()
&[u8] -> &str | s.to_vec() or s.to_owned()
&[u8] -> String | std::str::from_utf8(s).unwrap(), but don't**
&[u8] -> Vec | String::from_utf8(s).unwrap(), but don't**
Vec -> &str | &s if possible* else s.as_slice()
Vec -> String | std::str::from_utf8(&s).unwrap(), but don't**
Vec -> &[u8] | String::from_utf8(s).unwrap(), but don't**
* target should have explicit type (i.e., checker can't infer that)
** handle the error properly instead
Context
Stack Overflow Q#41034635, score: 220
Revisions (0)
No revisions yet.