像我这样的新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]

最佳答案

来自&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> -> &strVec<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/

    10-11 21:49