如何告诉 Rust 编译器您已经处理了“移动后此处使用的值”情况

问题描述 投票:0回答:1

这是我解决 leetcode 问题之一的代码:

    pub fn group_strings(strings: Vec<String>) -> Vec<Vec<String>> {
        let mut strings_iter = strings.into_iter();

        // Unwrap because the pblm guarantees that strings len >= 1
        let mut result = vec![vec![strings_iter.next().unwrap()]];

        let mut seq_found: bool = false;
        while let Some(input_string) = strings_iter.next() {
            // Is this string in seq with any of the strings in the result?
            for output_string_list in result.iter_mut() {
                if Solution::are_in_seq(&output_string_list[0], &input_string) {
                    // We are cloning because rust complains that we are using input_string
                    // after it is moved here, although seq_found flag ensures that we don't.
                    output_string_list.push(input_string);
                    seq_found = true;
                    break;
                }
            }

            if !seq_found {
                result.push(vec![input_string]);
            }
            seq_found = false;            
        }

        return result;
    }

我得到的编译器错误是:

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

如果

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

output_string_list.push(input_string.clone());

但是这种克隆是不必要的,并且可能是一项昂贵的操作。

rust borrow-checker
1个回答
0
投票

是的,通过使用控制流结构(编译器理解)而不是

bool
s 的值(编译器不理解)。使用标记循环,您可以
continue
循环,编译器会理解它会阻止循环体的其余部分执行,并且类似地理解,如果我们不
continue
,我们永远不会消耗
input_string
,因为它们发生了在同一个街区。

pub fn group_strings(strings: Vec<String>) -> Vec<Vec<String>> {
    let mut strings_iter = strings.into_iter();

    // Unwrap because the pblm guarantees that strings len >= 1
    let mut result = vec![vec![strings_iter.next().unwrap()]];

    'find: while let Some(input_string) = strings_iter.next() {
        // Is this string in seq with any of the strings in the result?
        for output_string_list in result.iter_mut() {
            if Solution::are_in_seq(&output_string_list[0], &input_string) {
                output_string_list.push(input_string);
                continue 'find;
            }
        }

        // can only get here if we never continued above, 
        // so `input_string` was definitely not moved
        result.push(vec![input_string]);
    }

    return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.