繁体   English   中英

如何在Rust中使用对象作为其自身方法的参数?

[英]How can I use an object as a parameter of its own method in Rust?

我在Rust中为简单的结构编写了以下代码。 这只是一个例子,没有太多真实的逻辑:

struct Vec2 {
    x: f32,
    y: f32,
}

impl Vec2 {
    fn multiply(&mut self, other: &Vec2) {
        self.x *= other.x;
        self.y *= other.y;
    }
}

我可以创建简单的向量,然后将向量与另一个向量相乘,但是当我尝试将向量与自身向量相乘时遇到一个问题:编译器抱怨我不能借用该向量可变,因为它也被借为不可变的。

fn main() {
    let mut vec = Vec2 { x: 2.0, y: 2.3 };
    vec.multiply(&vec);
}
error[E0502]: cannot borrow `vec` as mutable because it is also borrowed as immutable
  --> src/main.rs:15:5
   |
15 |     vec.multiply(&vec);
   |     ^^^^--------^----^
   |     |   |        |
   |     |   |        immutable borrow occurs here
   |     |   immutable borrow later used by call
   |     mutable borrow occurs here

这是有道理的,但是将这样的向量与其自身相乘的正确方法是什么? 更重要的是:对于一般情况,我需要使用自己的方法(使用与参数相同的结构)来修改结构。

我认为您已经理解了这一点,但是现在拥有的东西不起作用的原因是,不能将价值与可变借贷同时可变地借入。 为了执行方法是,你将需要两个可变借位(在形式&mut self )和不可变的借(在形式other: &Vec2在同一时间 由于您的方法适用于Vec2任何两个成员, Vec2始终会有两个单独的借用项:编译器无法推断出单个借用项对于将向量自身相乘的情况是有效的。

至于您的问题,您可以根据自己要执行的操作的详细信息有几种选择。

选项1:克隆

只需在Vec2的定义中添加#[derive(Clone)] ,您就可以使用clone方法clone该类型的元素。

#[derive(Clone)]
struct Vec2 {
    x: f32,
    y: f32,
}

impl Vec2 {
    fn multiply(&mut self, other: &Vec2) {
        self.x *= other.x;
        self.y *= other.y;
    }
}

fn main() {
    let mut vec = Vec2 { x: 2.0, y: 2.3 };
    vec.multiply(&vec.clone());
}

选项2:复制

如果您的类型很简单(只有两个浮点数),则可以合理地派生Copy 然后,将类型的元素简单地复制到函数中,而不需要引用。 这意味着,我们应该改变的签名Vec2::multiply采取other简单地Vec2 ,而不是&Vec2 (这不是绝对必要的,但采用指针通常是效率较低的Copy类型)。

#[derive(Copy, Clone)]
struct Vec2 {
    x: f32,
    y: f32,
}

impl Vec2 {
    fn multiply(&mut self, other: Vec2) {
        self.x *= other.x;
        self.y *= other.y;
    }
}

fn main() {
    let mut vec = Vec2 { x: 2.0, y: 2.3 };
    vec.multiply(vec);
}

选项3:专用方法

你可以有一个名为单独的方法multiply_selfsquare (取决于您的语义),只是需要&mut self 在使用自身修改结构的一般情况下,这可能是最好的选择。

struct Vec2 {
    x: f32,
    y: f32,
}

impl Vec2 {
    fn multiply_self(&mut self) {
        self.x *= self.x;
        self.y *= self.y;
    }
}

fn main() {
    let mut vec = Vec2 { x: 2.0, y: 2.3 };
    vec.multiply_self();
}

选项4:返回新值

您可能有一个方法不会让self变得可变,而是返回一个新的Vec2 然后可以执行vec = vec.multiply(&vec)

struct Vec2 {
    x: f32,
    y: f32,
}

impl Vec2 {
    fn multiply(&self, other: &Vec2) -> Vec2 {
        Vec2 {
            x: self.x * other.x,
            y: self.y * other.y,
        }
    }
}

fn main() {
    let mut vec = Vec2 { x: 2.0, y: 2.3 };
    vec = vec.multiply(&vec)
}

可能还有许多其他方法可以做到这一点,但这就是这种简单情况下的想法。 如果您分享有关您总体上想做什么的更多细节,我也许可以提出更多建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM