【问题标题】:How to create a String directly?如何直接创建字符串?
【发布时间】:2015-07-10 02:08:39
【问题描述】:

当我需要一个字符串时,有什么方法可以避免调用.to_string()?例如:

fn func1(aaa: String) -> ....

而不是

func1("fdsfdsfd".to_string())

我可以这样做吗:

func1(s"fdsfdsfd")

【问题讨论】:

    标签: rust


    【解决方案1】:

    TL;DR:

    截至Rust 1.9str::to_stringstr::to_ownedString::fromstr::into 都具有相同的性能特征。使用您喜欢的任何一个。


    将字符串切片 (&str) 转换为拥有的字符串 (String) 的最明显和惯用的方法是使用 ToString::to_string。这适用于实现Display 的任何类型。这包括字符串切片,还包括整数、IP 地址、路径、错误等。

    在 Rust 1.9 之前,to_stringstr 实现利用了 formatting infrastructure。虽然它有效,但它是矫枉过正的,并不是最高效的路径。

    更轻松的解决方案是使用ToOwned::to_owned,它是为具有“借用”和“拥有”对的类型实现的。是implemented in an efficient manner

    另一个轻量级的解决方案是使用Into::into,它利用了From::from。这也是implemented efficiently


    对于您的特定案例,最好的做法是接受&str,作为thirtythreeforty answered。然后你需要做零分配,这是最好的结果。

    一般来说,如果我需要创建一个分配的字符串,我可能会使用into——它只有4个字母长^_^。在回答有关 Stack Overflow 的问题时,我会使用 to_owned,因为这样会更明显。

    【讨论】:

      【解决方案2】:

      不,str::to_string() 方法是从 &'static str(字符串文字)创建 String 的规范方法。我什至喜欢它,因为你不喜欢它:它有点冗长。因为它涉及堆分配,所以在这种情况下调用它之前应该三思而后行。另请注意,由于Rust gained impl specializationstr::to_string 并不比str::to_owned 或其同类慢。

      然而,你真正想要的是一个func1,它可以很容易地传递任何字符串,无论是&str还是String。因为StringDeref 转换为&str,所以您可以让func1 接受&str,从而完全避免字符串分配。请参阅此示例 (playground):

      fn func1(s: &str) {
          println!("{}", s);
      }
      
      fn main() {
         let allocated_string: String = "owned string".to_string();
         func1("static string");
         func1(&allocated_string);
      }
      

      【讨论】:

      • to_string 仍然默认使用,即使它在技术上有点慢。但是,专业化就不会了。
      • 根据 alex crichton 的说法,to_string 是将 str 转换为 String 的惯用方式:github.com/rust-lang/rust/pull/26176
      • @steveklabnik 在那个 GitHub 链接上,你说“to_owned() 更适合通用代码。”这是为什么呢?
      • to_string 绝对是 惯用 选择——它只是目前不是高性能选择。大约六个月前,我 made a comment 替换 to_string 使我的代码占用了之前的 87%。
      • 3340,因为这是一种将借来的价值变成拥有价值的通用方式。
      【解决方案3】:

      dtolnay:

      我现在更喜欢 to_owned() 字符串文字,而不是 to_string()into()

      String&str 有什么区别?一个不满意的答案是“一个是字符串,另一个不是字符串”,因为显然两者都是字符串。获取字符串并使用 to_string() 将其转换为字符串似乎错过了我们首先要这样做的原因,更重要的是错过了向读者记录这一点的机会。

      String 和 &str 的区别在于一个是拥有的,一个是不拥有的。使用to_owned() 完全捕捉到了我们代码中特定位置需要转换的原因。

      struct Wrapper {
          s: String
      }
         
      // I have a string and I need a string. Why am I doing this again?
      Wrapper { s: "s".to_string() }
         
      // I have a borrowed string but I need it to be owned.
      Wrapper { s: "s".to_owned() }
      

      vitalyd:

      如果您将to_string 视为to_String,则不会

      【讨论】:

      • 您的意思是包含vitalyd 的评论吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2010-12-24
      • 1970-01-01
      • 1970-01-01
      • 2019-02-22
      相关资源
      最近更新 更多