如何告诉Rust编译器你已经处理了“Value used here after move”的情况

cxfofazt  于 2024-01-08  发布在  其他
关注(0)|答案(2)|浏览(265)

下面是我的一个leetcode问题的代码:

  1. pub fn group_strings(strings: Vec<String>) -> Vec<Vec<String>> {
  2. let mut strings_iter = strings.into_iter();
  3. // Unwrap because the pblm guarantees that strings len >= 1
  4. let mut result = vec![vec![strings_iter.next().unwrap()]];
  5. let mut seq_found: bool = false;
  6. while let Some(input_string) = strings_iter.next() {
  7. // Is this string in seq with any of the strings in the result?
  8. for output_string_list in result.iter_mut() {
  9. if Solution::are_in_seq(&output_string_list[0], &input_string) {
  10. // We are cloning because rust complains that we are using input_string
  11. // after it is moved here, although seq_found flag ensures that we don't.
  12. output_string_list.push(input_string);
  13. seq_found = true;
  14. break;
  15. }
  16. }
  17. if !seq_found {
  18. result.push(vec![input_string]);
  19. }
  20. seq_found = false;
  21. }
  22. return result;
  23. }

字符串
我得到的编译器错误是:

  1. Line 22, Char 34: use of moved value: `input_string` (solution.rs)
  2. |
  3. 9 | while let Some(input_string) = strings_iter.next() {
  4. | ------------
  5. | |
  6. | this reinitialization might get skipped
  7. | move occurs because `input_string` has type `std::string::String`, which does not implement the `Copy` trait
  8. ...
  9. 15 | output_string_list.push(input_string);
  10. | ------------ value moved here
  11. ...
  12. 22 | result.push(vec![input_string]);
  13. | ^^^^^^^^^^^^ value used here after move
  14. For more information about this error, try `rustc --explain E0382`.


我只在seq_found的情况下推送input_string。但是编译器会将其标记为move后可能使用。告诉编译器我处理了这种情况的最佳方法是什么?为了解决这个问题,我可以这样做:

  1. output_string_list.push(input_string.clone());


但这个克隆是不必要的,可能是一个昂贵的操作。

kqqjbcuj

kqqjbcuj1#

是的,通过使用控制流结构(编译器可以理解),而不是bool s的值(编译器不理解)。使用带标签的循环,你可以continue循环,编译器理解这会阻止循环体的其余部分执行,同样地,如果我们不continue,我们永远不会消耗input_string,因为它们发生在同一块中。

  1. pub fn group_strings(strings: Vec<String>) -> Vec<Vec<String>> {
  2. let mut strings_iter = strings.into_iter();
  3. // Unwrap because the pblm guarantees that strings len >= 1
  4. let mut result = vec![vec![strings_iter.next().unwrap()]];
  5. 'find: while let Some(input_string) = strings_iter.next() {
  6. // Is this string in seq with any of the strings in the result?
  7. for output_string_list in result.iter_mut() {
  8. if Solution::are_in_seq(&output_string_list[0], &input_string) {
  9. output_string_list.push(input_string);
  10. continue 'find;
  11. }
  12. }
  13. // can only get here if we never continued above,
  14. // so `input_string` was definitely not moved
  15. result.push(vec![input_string]);
  16. }
  17. return result;
  18. }

字符串
(顺便说一句,这段代码也要短得多,而且少了一个变量。

展开查看全部
wvyml7n5

wvyml7n52#

不使用for,这可能会混淆您的控制流,您可以使用一些迭代器操作来首先查找匹配列表,然后根据是否找到匹配来移动input_string

  1. pub fn group_strings(strings: Vec<String>) -> Vec<Vec<String>> {
  2. let mut strings_iter = strings.into_iter();
  3. // Unwrap because the pblm guarantees that strings len >= 1
  4. let mut result = vec![vec![strings_iter.next().unwrap()]];
  5. let mut seq_found: bool = false;
  6. while let Some(input_string) = strings_iter.next() {
  7. // Is this string in seq with any of the strings in the result?
  8. let maybe_output_string_list = result.iter_mut().find(|output_string_list| {
  9. Solution::are_in_seq(&output_string_list[0], &input_string)
  10. });
  11. if let Some(output_string_list) = maybe_output_string_list {
  12. output_string_list.push(input_string);
  13. } else {
  14. result.push(vec![input_string]);
  15. }
  16. }
  17. result
  18. }

字符串

展开查看全部

相关问题