How do I convert between String, &str, Vec<u8> and &[u8]?
12,434
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
Author by
Martin Algesten
Programmer with 15+ years experience. https://github.com/algesten
Updated on June 18, 2022Comments
-
Martin Algesten almost 2 years
A new Rustacean like me struggles with juggling these types:
String
,&str
,Vec<u8>
,&[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<u8> = ...;
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<u8> -> String String::from_utf8(v)
Ultimately I want a complete table of transitions for these types:
&str -> String &str -> &[u8] &str -> Vec<u8> String -> &str String -> &[u8] String -> Vec<u8> &[u8] -> &str &[u8] -> String &[u8] -> Vec<u8> Vec<u8> -> &str Vec<u8> -> String Vec<u8> -> &[u8]
-
piotao almost 4 yearsOK, but how to change a single u8 variable to string? to_string() seems to not work, since it yells "no method named
as_string
found for typeu8
in the current scope"... What I want is to change a small number (like 32) to string "32". -
rdxdkr almost 2 years@piotao for that you need to call
format!("{}", 5_u8)
, which returns an ownedString
.