首页 > 解决方案 > 为什么移动字符串变量会在这里出错?

问题描述

use std::collections::HashMap;
#[derive(Clone,Debug)]
pub enum Address {
    Ptr(Box<Node>),
    None,
}

#[derive(Clone,Debug)]
pub struct Node {
    connection: String,
    value: i32,
    next: Address,
}

impl Node {

    pub fn new(connection:String, value: i32) -> Node{
        Node{
            connection,
            value,
            next: Address::None,
        }
    }

    pub fn insert(&mut self, connection: String, value: i32) {
        match self.next {
            Address::Ptr(ref mut v) => {
                v.insert(connection,value);
            }
            Address::None => {
                self.next = Address::Ptr(Box::new(Node{connection,value,next:Address::None}))
            }
        }
    }
    
}


struct GraphAdj {
    vec_edge: HashMap<String,Node>
}

impl GraphAdj {
    pub fn new() -> GraphAdj{
        GraphAdj{
            vec_edge: HashMap::new(),
        }
    }

    pub fn insert(&mut self, value: String) -> Result<(),String> {

        if self.vec_edge.contains_key(&value) {
            return Err(format!("Key already present"))
        }

        self.vec_edge.insert(value,
            Node::new(String::from(""),-1)
        );
        Ok(())
    } 

    pub fn add_connection(&mut self, 
        source_vertex: String,
        destination_vertex: String,
        cost: i32,
    ){

        for (key,value) in self.vec_edge.iter_mut() {
            if *key == source_vertex {
                value.insert(destination_vertex,cost);
            } 
        }
    }

}
fn main(){}

我收到以下错误

***cargo check
    Checking rust_graph v0.1.0 (D:\projects\DSA\graph\rust_graph)
error[E0382]: use of moved value: `destination_vertex`
  --> src\main.rs:36:30
   |
30 |         destination_vertex: String,
   |         ------------------ move occurs because `destination_vertex` has type `String`, which does not implement the `Copy` trait
...
36 |                 value.insert(destination_vertex,cost);
   |                              ^^^^^^^^^^^^^^^^^^ value moved here, in previous iteration of loop
error: aborting due to previous error***

***For more information about this error, try `rustc --explain E0382`.
error: could not compile `rust_graph`
To learn more, run the command again with --verbose.***

我知道 String 变量已移动,但为什么这里有问题?我的意思是无论如何我以后都不会使用它。

标签: rust

解决方案


这是发生错误的函数:

   pub fn add_connection(
        &mut self,
        source_vertex: String,
        destination_vertex: String,
        cost: i32,
    )
    {
        for (key, value) in self.vec_edge.iter_mut() {
            if *key == source_vertex {
                value.insert(destination_vertex, cost);
            }
        }
    }

这是insert()我们得到错误的定义:

pub fn insert(&mut self, connection: String, value: i32)

因此,您有一个String实例,您尝试多次移动,方法是将其作为参数传递给insert(). 每次调用循环都会移动字符串,移动一次后就不能再移动了。

编译器无法知道此循环将进行多少次迭代或条件*key == source_vertex将评估为真多少次,因此它假定它可能会发生多次。

为了解决错误,您必须对clone()字符串并移动(作为参数传递)克隆:

  for (key, value) in self.vec_edge.iter_mut() {
       if *key == source_vertex {
           value.insert(destination_vertex.clone(), cost);
       }
  }

或者一旦值被移动就从循环中中断:

for (key, value) in self.vec_edge.iter_mut() {
    if *key == source_vertex {
       value.insert(destination_vertex, cost);
       return; // or break; -> exit from the loop or method
    }
}

推荐阅读