【问题标题】:Insert constructed string into Vec in Rust在 Rust 中将构造的字符串插入 Vec
【发布时间】:2019-12-31 05:43:11
【问题描述】:

现在我正在编写一个程序,其中我正在使用基于 for 循环中的条件构造的字符串来更新 Vec。我正在尝试做的一个(非常做作的)简化形式如下:

fn main() {
    let mut arr = vec!["_"; 5];
    for (i, chr) in "abcde".char_indices() {
        arr[i] = &chr.to_string().repeat(3);
    }
}

但是,我收到了错误 temporary value dropped while borrowed。关于在这里做什么的任何指示?

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    arr 的生命周期是main 方法的作用域,而chr.to_string() 仅在 for 循环体中有效。分配它会导致错误。

    您可以通过使用Vec<String> 而不是Vec<&str> 来避免此问题。

    fn main() {
      let mut arr = vec!["_".to_string(); 5];
      for (i, chr) in "abcde".char_indices() {
        arr[i] = chr.to_string().repeat(3);
      }
    }
    

    这里我们看到 String "_".to_string() 被复制了五次(效率不高)。我怀疑在你的真实代码中情况并非如此。

    【讨论】:

    • 虽然这解决了 OP 的问题,但应该注意@wasmup 的答案使用更惯用的 Rust 产生了相同的结果
    【解决方案2】:

    也可以使用字符串尝试this 一个衬里:

    let arr: Vec<String> = "abcde".chars().map(|c| c.to_string().repeat(3)).collect();
    
    

    输出:

    ["aaa", "bbb", "ccc", "ddd", "eee"]
    

    【讨论】:

      【解决方案3】:

      正如其他人所提到的,您正在创建的String必须归某人所有,否则他们最终会被丢弃。当编译器检测到当你的数组仍然持有对它们的引用时发生了这种下降,它会抱怨。

      您需要考虑谁需要拥有这些价值观。如果您最终的阵列是他们居住的自然场所,请在那儿 move 他们:

      fn main() {
          let mut arr = Vec::with_capacity(5);
          for (i, chr) in "abcde".char_indices() {
              arr.push(chr.to_string().repeat(3));
          }
      }
      

      如果您绝对需要一个 &amp;str 数组,您仍然需要将这些值保持“活动”至少与引用本身一样长:

      fn i_only_consume_refs(data: Vec<&String>) -> () {}
      
      fn main() {
          let mut arr = Vec::with_capacity(5);
          for (i, chr) in "abcde".char_indices() {
              arr.push(chr.to_string().repeat(3));
          }
          let refs = arr.iter().collect();
          i_only_consume_refs(refs)
      }
      

      在这里,我们仍然将所有创建的Strings 移动到向量arr,然后对其元素进行引用。这样,只要arr(拥有字符串),引用向量就有效。

      TL;DR:有人需要拥有这些Strings,而你保留对它们的引用。你不能创建临时字符串,只能存储引用,否则你会引用一个丢弃的值,这确实很糟糕,编译器不会让你这样做。

      【讨论】:

      • 第一个示例中的移动到底发生在哪里?我不是说代码错了,但作为对 Rust 不太熟悉的人,我不明白。
      【解决方案4】:

      问题是arr 只保存引用,而里面的字符串必须在别处拥有。一种可能的解决方法是简单地泄漏您在循环中创建的瞬态字符串。

      fn main() {
          let mut arr = vec!["_"; 5];
          for (i, chr) in "abcde".char_indices() {
              arr[i] = Box::leak(Box::new(chr.to_string().repeat(3)));
          }
      }
      

      【讨论】:

      • 泄漏意味着被引用的Box以后永远不会从内存中删除。
      猜你喜欢
      • 2022-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多