Kno*_*kko 2 methods mutability rust borrow-checker
我在Rust中为简单的结构编写了以下代码。这只是一个例子,没有太多真实的逻辑:
struct Vec2 {
x: f32,
y: f32,
}
impl Vec2 {
fn multiply(&mut self, other: &Vec2) {
self.x *= other.x;
self.y *= other.y;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以创建简单的向量,然后将向量与另一个向量相乘,但是当我尝试将向量与自身向量相乘时遇到了一个问题:编译器抱怨我不能借用该向量,因为它也被借为不可变的。
fn main() {
let mut vec = Vec2 { x: 2.0, y: 2.3 };
vec.multiply(&vec);
}
Run Code Online (Sandbox Code Playgroud)
struct Vec2 {
x: f32,
y: f32,
}
impl Vec2 {
fn multiply(&mut self, other: &Vec2) {
self.x *= other.x;
self.y *= other.y;
}
}
Run Code Online (Sandbox Code Playgroud)
这是有道理的,但是将这样的向量与其自身相乘的正确方法是什么?更重要的是:对于一般情况,我需要使用自己的方法(使用与参数相同的结构)来修改结构。
我认为您已经理解了这一点,但是现在拥有的东西不起作用的原因是,不能将价值与可变借贷同时可变地借入。为了执行方法是,你将需要两个可变借(的形式&mut self)和不可变的借(的形式other: &Vec2),在同一时间。由于您的方法适用于的任何两个成员Vec2,因此您将始终有两个单独的借用项:编译器无法推断出将向量自身相乘的情况,单次借用将起作用。
至于您的问题,您可以根据自己要执行的操作的详细信息有几种选择。
只需添加#[derive(Clone)]对的定义,Vec2就可以使用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());
}
Run Code Online (Sandbox Code Playgroud)
如果您的类型很简单(只有两个浮点数),则可以合理地派生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);
}
Run Code Online (Sandbox Code Playgroud)
You could have a separate method called multiply_self or square (depending on your semantics) that just takes &mut self. This might be your best bet in the general case of modifying a struct using itself.
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();
}
Run Code Online (Sandbox Code Playgroud)
You could have a method that doesn't take self mutably and instead returns a new Vec2. Then you could do 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)
}
Run Code Online (Sandbox Code Playgroud)
There are probably lots of other ways to do this, but this is what comes to mind in this simple case. If you share more details about what your trying to do in general, I might be able to come up with more.
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |