为什么在此处移动字符串变量会出错?

问题描述

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,next:Address::None}))
            }
        }
    }
    
}


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

impl GraphAdj {
    pub fn new() -> GraphAdj{
        GraphAdj{
            vec_edge: HashMap::new(),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 变量被移动了,但为什么这里有问题?我的意思是无论如何我都不会使用它。

解决方法

这是发生错误的函数:

   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 将计算为 true 的次数,因此它假设它可能发生多次。

为了解决错误,您必须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
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...