“无法移出借用的内容”;从结构字段分配变量时 [英] "cannot move out borrowed content" when assigning a variable from a struct field

查看:98
本文介绍了“无法移出借用的内容”;从结构字段分配变量时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Rust,并且正在与借阅检查器对抗。

I'm learning Rust and I'm fighting against the borrow checker.

我有一个基本的 Point 结构。我有一个 scale 函数,该函数可以修改该点的所有坐标。我想从另一个名为 convert 的方法调用此方法:

I have a basic Point structure. I have a scale function that modifies all the coordinates of the point. I would like to call this method from another method named convert:

struct AngleUnit;

struct Point {
    x: f32,
    y: f32,
    z: f32,
    unit: AngleUnit,
}

fn factor(_from: AngleUnit, _to: AngleUnit) -> f32 {
    1.0
}

impl Point {
    pub fn new(x: f32, y: f32, z: f32, unit: AngleUnit) -> Point {
        Point { x, y, z, unit }
    }

    fn scale(&mut self, factor: f32) {
        self.x *= factor;
        self.y *= factor;
        self.z *= factor;
    }

    fn convert(&mut self, unit: AngleUnit) {
        let point_unit = self.unit;
        self.scale(factor(point_unit, unit));
    }
}

现在我遇到以下错误:

cannot move out of borrowed content

我在做什么错了?

推荐答案

完成错误消息状态:

error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:26:26
   |
26 |         let point_unit = self.unit;
   |                          ^^^^^^^^^
   |                          |
   |                          cannot move out of borrowed content
   |                          help: consider borrowing here: `&self.unit`

了解移动的位置很有用

最简单的解决方案是实施 Copy 或<$ c为您的 AngleUnit 类型创建$ c>克隆。如果它是复制,则您的代码将保持原样。如果只是克隆,则必须显式调用 .clone()进行复制。

The simplest solution is to implement either Copy or Clone for your AngleUnit type. If it's Copy, your code will work as-is. If it's only Clone, you have to explicitly call .clone() to make a duplicate.

如果无法进行复制复制,则可以使用引用,如编译器建议的那样:

If your type cannot be made Copy, then you can use references, as the compiler suggests:

fn factor(_from: &AngleUnit, _to: &AngleUnit) -> f32 {
    1.0
}



fn convert(&mut self, unit: AngleUnit) {
    let point_unit = &self.unit;
    self.scale(factor(point_unit, &unit));
}

最初的问题都归结为这一行:

The original problem all boils down to this line:

let point_unit = self.unit;

point_unit 的值应该是什么?

如果我们的值从 self.unit 移至 point_unit ,那么 self.unit 的值是多少? 简单的解决方案是,它是未定义的内存,但是经验表明,我们的程序员会解决这个问题,并引入令人兴奋的调试问题。

If we moved the value from self.unit to point_unit, then what would the value of self.unit be? The "easy" solution would be that it is undefined memory, but experience has shown that we programmers will screw that up and introduce exciting-to-debug problems.

我们可以自动复制该值,但是如果 AngleUnit 是一种占用10 MiB空间的类型会怎样?然后,无辜的眼神吸引了很多记忆和时间。

We could copy the value automatically, but what would happen if AngleUnit were a type that took up 10 MiB of space? Then an innocent looking line just sucked up a bunch of memory and time. That's not very nice either.

相反,Rust做到了这一点,默认情况下类型被移动了 并且您不能使对象处于未定义状态。某些类型可以选择自动复制的功能-这是 Copy 特性。您还可以显式复制类型- Clone 特性。您还可以获取现有值的引用并将其传递给周围。借阅检查器将使您不再使用该引用,之后它就不再有效。

Instead, Rust makes it so that types are moved by default and you cannot leave an object in an undefined state. Certain types can opt into the ability to be automatically copied — this is the Copy trait. You can also allow types to be explicitly copied — the Clone trait. You can also obtain a reference to an existing value and pass that around. The borrow checker will prevent you from using that reference after it is no longer valid.

这篇关于“无法移出借用的内容”;从结构字段分配变量时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆