像我这样的新Rustacean在努力处理以下类型:String
,&str
,Vec<u8>
和&[u8]
。
随着时间的流逝,我希望有一个顿悟,并突然明白为什么某些图书馆调用使用一个或另一个。在此之前,我需要帮助来规划每个惯用的过渡。
鉴于以下类型:
let st: &str = ...;
let s: String = ...;
let u: &[u8] = ...;
let v: Vec<u8> = ...;
我想我已经弄清楚了,但是它们是惯用的吗?
&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)
最终,我想要这些类型的转换的完整表:
&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]
最佳答案
来自&str
&str -> String
具有many equally valid methods:String::from(st)
,st.to_string()
和st.to_owned()
。String::from
的主要优点是您可以将其用作map
方法的参数。因此,通常可以使用x.map(|s| String::from(s))
代替x.map(String::from)
。 &str
-> &[u8]
由st.as_bytes()
完成&str
-> Vec<u8>
是&str -> &[u8] -> Vec<u8>
的组合,即st.as_bytes().to_vec()
或st.as_bytes().to_owned()
来自
String
String -> &str
应该是可以强制使用的&s
,否则应该是s.as_str()
。 String -> &[u8]
与&str -> &[u8]
相同:s.as_bytes()
String -> Vec<u8>
有一个自定义方法:s.into_bytes()
来自
&[u8]
&[u8] -> Vec<u8>
由u.to_owned()
或u.to_vec()
完成。他们做同样的事情,但是to_vec
的一点好处是它返回的类型是明确的。 &[u8] -> &str
实际上不存在,应该是&[u8] -> Result<&str, Error>
,它是通过str::from_utf8(u)
提供的str::from_utf8(u).unwrap()
可以工作,但是您应该首选更好的错误处理(请参阅Error handling - The Result type)。 &[u8] -> String
是&[u8] -> Result<&str, Error> -> Result<String, Error>
的组合String::from_utf8(u).unwrap()
可以工作,但是希望有更好的错误处理(请参见Error handling - The Result type以及 Result::map
。来自
Vec<u8>
Vec<u8> -> &[u8]
应该是可以强制使用的&v
,否则应该是as_slice
。 Vec<u8> -> &str
与Vec<u8> -> &[u8] -> Result<&str, Error>
相同,即str::from_utf8(&v)
str::from_utf8(&v).unwrap()
可以工作,但是更喜欢更好的错误处理(请参阅Error handling - The Result type)Vec<u8> -> String
实际上不存在,通过Vec<u8> -> Result<String, Error>
可以是String::from_utf8(v)
String::from_utf8(v).unwrap()
可以工作,但是希望有更好的错误处理(请参阅Error handling - The Result type)。 只要目标不是通用目标,而显式键入分别为
&str
或&[u8]
,就可以使用强制转换。 Rustonomicon在coercions上有一章,其中包含有关强制站点的更多详细信息。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
关于rust - String,&str,Vec <u8>和&[u8]的惯用转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41034635/