rust 所有权的问题?

  struct Animate {
    name: String
  }

  impl Animate {
    fn get_name(&self) -> String {
      return self.name;
    }
  }

  let animate = Animate {
    name: String::from("dog")
  };

  println!("{}", animate.get_name());

如果运行上面的程序,会报错误

cannot move out of `self.name` which is behind a shared reference

修复的方法可以是

fn get_name(&self) -> &String {
      return &self.name;
    }
或者是
fn get_name(&self) -> String {
      return self.name.clone();
    }

这个问题应该是和 rust 所有权有关,当方法返回时会出现所有权移动。一开始认为可能是结构体内的字段无法移动所有权。但是执行

let a_name = animate.name;

// println!("{}", animate.name) 报错了
// println!("{}", a_name) 没有问题

报错的原因应该是所有权移动后, animate.name 就失效了,按这么说结构体内的字段是可以移动所有权的。

那最上面的报错应该怎么比较好去理解?

阅读 1.1k
3 个回答

并不是结构体成员不能 move 。

你的成员函数里,self 是一个 reference 。reference 并没有所有权,所以也就无法发生所有权移动。

rust 中结构体是一个容器,这个容器里的元素可能在这个容器里,但如果你想使用容器里的元素,需要把这些元素在容器中取出来,即所有权的变化。

struct Animate {
  name: String
}

impl Animate {
  fn get_name(&self) -> String {
    return self.name;  // 元素从容器中取了出来,容器里就没有这个元素了
  }
}

let a_name = animate.name; // 元素从容器中取了出来,容器里就没有这个元素了

如果在使用时不想在容器中取元素后发生所有权转移,就需要使用引用,意思是,我引用你容器里的元素,元素还在容器里,不需要移动。

    fn get_name(&self) -> &str {
      return &self.name;  // 获取容器内元素的引用,而不是直接取元素,则不会发生容器内元素的所有权转移
    }

    fn get_name(&self) -> String {
      return self.name.clone(); // 获取容器内元素的复制体,而不是直接取元素,则不会发生容器内元素的所有权转移
    }

let a_name = animate.name.as_str(); // 获取容器内元素的引用,而不是直接取元素,则不会发生容器内元素的所有权转移

这是 rust 的特性之一,需要适应一段时间。

其实很简单 因为你get_name没有取得animate的所有权,所以不能直接move,你只能返回&str或者Copy(这样可以保证后续继续可以调用get_name)
你把&self改成self 就能move了, 但是后续也无法继续使用animate

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏