【问题标题】:How do I convert between String, &str, Vec<u8> and &[u8]?如何在 String、&str、Vec<u8> 和 &[u8] 之间进行转换?
【发布时间】:2020-06-06 01:44:18
【问题描述】:

像我这样的新 Rustacean 难以兼顾这些类型:String&amp;strVec&lt;u8&gt;&amp;[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]

【问题讨论】:

    标签: string rust type-conversion


    【解决方案1】:

    来自&amp;str

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

    来自String

    • String -&gt; &amp;str 应该只是 &amp;s 强制可用或 s.as_str() 不可用。
    • String -&gt; &amp;[u8]&amp;str -&gt; &amp;[u8] 相同:s.as_bytes()
    • String -&gt; Vec&lt;u8&gt; 有一个自定义方法:s.into_bytes()

    来自&amp;[u8]

    • &amp;[u8] -&gt; Vec&lt;u8&gt;u.to_owned()u.to_vec() 完成。他们做同样的事情,但to_vec 有一点优势,即它返回的类型明确。
    • &amp;[u8] -&gt; &amp;str 实际上并不存在,那就是 &amp;[u8] -&gt; Result&lt;&amp;str, Error&gt;,通过 str::from_utf8(u) 提供
    • &amp;[u8] -&gt; String&amp;[u8] -&gt; Result&lt;&amp;str, Error&gt; -&gt; Result&lt;String, Error&gt; 的组合

    来自Vec&lt;u8&gt;

    • Vec&lt;u8&gt; -&gt; &amp;[u8] 应该只是 &amp;v 可以使用强制,或者as_slice 不可以。
    • Vec&lt;u8&gt; -&gt; &amp;strVec&lt;u8&gt; -&gt; &amp;[u8] -&gt; Result&lt;&amp;str, Error&gt; 相同,即 str::from_utf8(&amp;v)
    • Vec&lt;u8&gt; -&gt; String 实际上并不存在,那将是 Vec&lt;u8&gt; -&gt; Result&lt;String, Error&gt; 通过 String::from_utf8(v)

    只要目标不是通用的,而是分别显式键入为&amp;str&amp;[u8],就可以使用强制转换。 Rustonomicon 在coercions 上有一个章节,其中包含有关强制站点的更多详细信息。


    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_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
    

    【讨论】:

    • 好的,但是如何将单个 u8 变量更改为字符串? to_string() 似乎不起作用,因为它大喊“在当前范围内找不到名为 as_string 的类型 u8 的方法”......我想要的是将一个小数字(如 32)更改为字符串“32” .
    猜你喜欢
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 2021-07-31
    • 2021-03-18
    • 1970-01-01
    • 2015-09-26
    • 1970-01-01
    相关资源
    最近更新 更多