Converting Rust String to and From
Rust &str
and String
is different in a sense that str
is static, owned and fix sized while String
can be dynamically allocated once and be converted to mutable to be appended. Most of the time you’ll be working with String
on Rust when re-allocating and moving values between structs
.
There are times you may need to convert dynamic string to char bytes and static string. Here are ways to do it:
From &str
&str -> String
has 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::from
is that you can use it as an argument to amap
method. So instead ofx.map(|s| String::from(s))
you can often usex.map(String::from)
.
- But I suggest you stick with one of them within a single project. The major advantage of
&str
->&[u8]
is done byst.as_bytes()
&str
->Vec<u8>
is a combination of&str -> &[u8] -> Vec<u8>
, i.e.st.as_bytes().to_vec()
orst.as_bytes().to_owned()
From String
String -> &str
should just be&s
where coercion is available ors.as_str()
where it is not.String -> &[u8]
is the same as&str -> &[u8]
:s.as_bytes()
String -> Vec<u8>
has a custom method:s.into_bytes()
From &[u8]
&[u8] -> Vec<u8>
is done byu.to_owned()
oru.to_vec()
. They do the same thing, butto_vec
has the slight advantage of being unambiguous about the type it returns.&[u8] -> &str
doesn’t actually exist, that would be&[u8] -> Result<&str, Error>
, 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] -> String
is the combination of&[u8] -> Result<&str, Error> -> Result<String, Error>
String::from_utf8(u).unwrap()
works, but prefer better error handling (see Error handling – The Result type and alsoResult::map
.
From Vec<u8>
Vec<u8> -> &[u8]
should be just&v
where coercion is available, oras_slice
where it’s not.Vec<u8> -> &str
is the same asVec<u8> -> &[u8] -> Result<&str, Error>
i.e.str::from_utf8(&v)
str::from_utf8(&v).unwrap()
works, but prefer better error handling (see Error handling – The Result type)
Vec<u8> -> String
doesn’t actually exist, that would beVec<u8> -> Result<String, Error>
viaString::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<u8> | 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<u8> | 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<u8> | String::from_utf8(s).unwrap(), but don't**
Vec<u8> -> &str | &s if possible* else s.as_slice()
Vec<u8> -> String | std::str::from_utf8(&s).unwrap(), but don't**
Vec<u8> -> &[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