String,&amp; str,Vec <u8>和&amp; [u8]的惯用语转换

时间:2016-12-08 08:09:01

标签: rust type-conversion

像我这样的新的Rustacean在处理这些类型时遇到了困难:String&strVec<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]

1 个答案:

答案 0 :(得分:31)

来自&str

  • &str -> Stringmany equally valid methodsString::from(st)st.to_string()st.to_owned()
    • 但我建议你在一个项目中坚持使用其中一个。 String::from的主要优点是您可以将其用作map方法的参数。因此,您可以经常使用x.map(|s| String::from(s))
    • 而不是x.map(String::from)
  • &str - &gt; &[u8]st.as_bytes()
  • 完成
  • &str - &gt; Vec<u8>&str -> &[u8] -> Vec<u8>的组合,即st.as_bytes().to_owned()

来自String

  • String -> &str应该是&s强制可用,s.as_str()不是。{/ li>
  • String -> &[u8]&str -> &[u8]s.as_bytes()
  • 相同
  • String -> Vec<u8>有一个自定义方法:s.into_bytes()

来自&[u8]

  • &[u8] -> Vec<u8>u.to_owned()
  • 完成
  • &[u8] -> &str实际上并不存在,即&[u8] -> Result<&str, Error>,通过str::from_utf8(u)提供
  • &[u8] -> String&[u8] -> Result<&str, Error> -> Result<String, Error>的组合

来自Vec<u8>

  • Vec<u8> -> &[u8]应该只有&v强制可用,或as_slice不在其中。
  • Vec<u8> -> &strVec<u8> -> &[u8] -> Result<&str, Error>相同,即str::from_utf8(&v)
  • Vec<u8> -> String实际上并不存在,Vec<u8> -> Result<String, Error>来自String::from_utf8(v)

只要目标不是通用的,但分别明确键入&str&[u8],就可以使用强制

TL;博士

&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