rust - Transformaciones idiomáticas para String, & str, Vec<u8> y &
type-conversion (1)
Un nuevo Rustáceo como yo lucha con hacer malabarismos con estos tipos: String
, &str
, Vec<u8>
, &[u8]
.
Con el tiempo, espero tener una epifanía y de repente entender por qué algunas llamadas de biblioteca usan una u otra. Hasta entonces, necesito ayuda para trazar cada transición idiomática.
Teniendo en cuenta estos tipos:
let st: &str = ...;
let s: String = ...;
let u: &[u8] = ...;
let v: Vec<u8> = ...;
Creo que he descubierto esto, pero ¿son idiomáticos?
&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)
En última instancia, quiero una tabla completa de transiciones para estos tipos:
&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]
Desde &str
-
&str -> String
tiene muchos métodos igualmente válidos :String::from(st)
,st.to_string()
,st.to_owned()
.- Pero te sugiero que te quedes con uno de ellos dentro de un solo proyecto. La principal ventaja de
String::from
es que puede usarlo como un argumento para un método demap
. Entonces, en lugar dex.map(|s| String::from(s))
a menudo se puede usarx.map(String::from)
.
- Pero te sugiero que te quedes con uno de ellos dentro de un solo proyecto. La principal ventaja de
-
&str
->&[u8]
se realiza mediantest.as_bytes()
-
&str
->Vec<u8>
es una combinación de&str -> &[u8] -> Vec<u8>
, es decir,st.as_bytes().to_owned()
De la String
-
String -> &str
solo debe estar&s
donde la coerción está disponible os.as_str()
donde no lo está. -
String -> &[u8]
es lo mismo que&str -> &[u8]
:s.as_bytes()
-
String -> Vec<u8>
tiene un método personalizado:s.into_bytes()
Desde &[u8]
-
&[u8] -> Vec<u8>
se realiza medianteu.to_owned()
-
&[u8] -> &str
no existe realmente, eso sería&[u8] -> Result<&str, Error>
, proporcionado a través destr::from_utf8(u)
-
str::from_utf8(u).unwrap()
funciona, pero debería preferir un mejor manejo de errores (consulte Manejo de errores - El tipo de resultado ).
-
-
&[u8] -> String
es la combinación de&[u8] -> Result<&str, Error> -> Result<String, Error>
-
String::from_utf8(u).unwrap()
funciona, pero prefiere un mejor manejo de errores (vea Manejo de errores - El tipo de resultado y tambiénResult::map
.
-
Desde Vec<u8>
-
Vec<u8> -> &[u8]
debe ser justo&v
donde esté disponible la coerción, oas_slice
donde no esté. -
Vec<u8> -> &str
es lo mismo queVec<u8> -> &[u8] -> Result<&str, Error>
es decir,str::from_utf8(&v)
-
str::from_utf8(&v).unwrap()
funciona, pero prefiere un mejor manejo de errores (ver Manejo de errores - El tipo de resultado )
-
-
Vec<u8> -> String
no existe realmente, eso seríaVec<u8> -> Result<String, Error>
través de laString::from_utf8(v)
-
String::from_utf8(v).unwrap()
funciona, pero prefiere un mejor manejo de errores (consulte Manejo de errores - El tipo de resultado ).
-
La coerción está disponible siempre que el objetivo no sea genérico sino explícitamente escrito como &str
o &[u8]
respectivamente
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_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_owned()
&[u8] -> String | 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::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