这是我解决 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());
但是这种克隆是不必要的,并且可能是一项昂贵的操作。
是的,通过使用控制流结构(编译器理解)而不是
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;
}