如何编译以下 Rust 代码?
How do I make the following Rust code compile?
我是 Rust 编程语言的新手,我只是在玩弄它。我读了 Rust 的借用的东西,我想我明白为什么编译器不接受下面的代码,但我不知道如何让它正确:
struct Pixel;
struct Canvas {
pixel : Pixel,
}
impl Canvas {
fn drawPixel(&mut self, y : usize, x : usize, pixel : &Pixel) {
// Modify internal pixmap using given Pixel description.
}
fn setPixel(&mut self, y : usize, x : usize) {
// Draw a pixel to internal pixmap using own pixel description.
self.drawPixel(y, x, &self.pixel);
}
}
这是编译器报错:
src/main.rs:14:35: 14:45 error: cannot borrow `self.pixel` as immutable because `*self` is also borrowed as mutable
src/main.rs:14 self.drawPixel(y, x, &self.pixel);
^~~~~~~~~~
src/main.rs:14:13: 14:17 note: previous borrow of `*self` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*self` until the borrow ends
src/main.rs:14 self.drawPixel(y, x, &self.pixel);
^~~~
src/main.rs:14:46: 14:46 note: previous borrow ends here
src/main.rs:14 self.drawPixel(y, x, &self.pixel);
这个例子的想法是有一个方法'drawPixel'可以根据指定的'Pixel'绘制一个像素。第二个方法 'setPixel' 只是转发给前一个方法,将对与 'Canvas' 对象关联的 'Pixel' 实例的引用传递给它。
请不要问我为什么要这样做。这是我的真实用例的简化版本。我真的很想知道我能做些什么来编译这段代码。
如何使其正确取决于您的需要以及 Pixel 在实际代码中的实际外观。
由于 Pixel 可能是一个可以轻松复制的轻量级对象,因此您可以按值传递它。
#[derive(Copy, Clone)]
struct Pixel;
struct Canvas {
pixel : Pixel,
}
impl Canvas {
fn drawPixel(&mut self, y : usize, x : usize, pixel : Pixel) {
// Modify internal pixmap using given Pixel description.
}
fn setPixel(&mut self, y : usize, x : usize) {
// Draw a pixel to internal pixmap using own pixel description.
self.drawPixel(y, x, self.pixel);
}
}
根本问题是 setPixel
中对 drawPixel
的调用为 pixel
字段提供了 drawPixel
两个别名:一个可变的 self
(如 self.pixel
),以及通过 pixel
参数的不可变参数。在 Rust 中,非 mut
指针实际上是 指向 不可变 值的指针。但是,使用这两个别名,drawPixel
将能够改变 pixel
参数所指的像素值,并且其值会发生意外变化。
如果 Pixel
是一个小类型(比如 RGBA 四边形)并且没有实现 Drop
,您可以将其设为 Copy
,然后只需传递 Pixel
按值(参见 )。
如果这不可能,那么请考虑 drawPixel
实际需要变异的是什么。它需要改变 pixel
字段吗?如果是,您需要以某种方式复制像素,否则 pixel
参数的值将在您改变字段时发生变化,正如我在上面解释的那样。在这种情况下,您可能只能实现 Clone
并使用 clone()
方法来获取像素的副本。
如果你不需要改变drawPixel
中的pixel
字段,那么你可以将你改变的字段移动到一个单独的结构中,并移动drawPixel
方法改为那个结构。这样,&mut self
将应用于内部结构,确保不会与 pixel
字段混淆。
struct Pixel;
struct Canvas2;
struct Canvas {
canvas2 : Canvas2,
pixel : Pixel,
}
impl Canvas2 {
fn drawPixel(&mut self, y : usize, x : usize, pixel : &Pixel) {
// Modify internal pixmap using given Pixel description.
}
}
impl Canvas {
fn setPixel(&mut self, y : usize, x : usize) {
// Draw a pixel to internal pixmap using own pixel description.
self.canvas2.drawPixel(y, x, &self.pixel);
}
}
我是 Rust 编程语言的新手,我只是在玩弄它。我读了 Rust 的借用的东西,我想我明白为什么编译器不接受下面的代码,但我不知道如何让它正确:
struct Pixel;
struct Canvas {
pixel : Pixel,
}
impl Canvas {
fn drawPixel(&mut self, y : usize, x : usize, pixel : &Pixel) {
// Modify internal pixmap using given Pixel description.
}
fn setPixel(&mut self, y : usize, x : usize) {
// Draw a pixel to internal pixmap using own pixel description.
self.drawPixel(y, x, &self.pixel);
}
}
这是编译器报错:
src/main.rs:14:35: 14:45 error: cannot borrow `self.pixel` as immutable because `*self` is also borrowed as mutable
src/main.rs:14 self.drawPixel(y, x, &self.pixel);
^~~~~~~~~~
src/main.rs:14:13: 14:17 note: previous borrow of `*self` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*self` until the borrow ends
src/main.rs:14 self.drawPixel(y, x, &self.pixel);
^~~~
src/main.rs:14:46: 14:46 note: previous borrow ends here
src/main.rs:14 self.drawPixel(y, x, &self.pixel);
这个例子的想法是有一个方法'drawPixel'可以根据指定的'Pixel'绘制一个像素。第二个方法 'setPixel' 只是转发给前一个方法,将对与 'Canvas' 对象关联的 'Pixel' 实例的引用传递给它。
请不要问我为什么要这样做。这是我的真实用例的简化版本。我真的很想知道我能做些什么来编译这段代码。
如何使其正确取决于您的需要以及 Pixel 在实际代码中的实际外观。
由于 Pixel 可能是一个可以轻松复制的轻量级对象,因此您可以按值传递它。
#[derive(Copy, Clone)]
struct Pixel;
struct Canvas {
pixel : Pixel,
}
impl Canvas {
fn drawPixel(&mut self, y : usize, x : usize, pixel : Pixel) {
// Modify internal pixmap using given Pixel description.
}
fn setPixel(&mut self, y : usize, x : usize) {
// Draw a pixel to internal pixmap using own pixel description.
self.drawPixel(y, x, self.pixel);
}
}
根本问题是 setPixel
中对 drawPixel
的调用为 pixel
字段提供了 drawPixel
两个别名:一个可变的 self
(如 self.pixel
),以及通过 pixel
参数的不可变参数。在 Rust 中,非 mut
指针实际上是 指向 不可变 值的指针。但是,使用这两个别名,drawPixel
将能够改变 pixel
参数所指的像素值,并且其值会发生意外变化。
如果 Pixel
是一个小类型(比如 RGBA 四边形)并且没有实现 Drop
,您可以将其设为 Copy
,然后只需传递 Pixel
按值(参见
如果这不可能,那么请考虑 drawPixel
实际需要变异的是什么。它需要改变 pixel
字段吗?如果是,您需要以某种方式复制像素,否则 pixel
参数的值将在您改变字段时发生变化,正如我在上面解释的那样。在这种情况下,您可能只能实现 Clone
并使用 clone()
方法来获取像素的副本。
如果你不需要改变drawPixel
中的pixel
字段,那么你可以将你改变的字段移动到一个单独的结构中,并移动drawPixel
方法改为那个结构。这样,&mut self
将应用于内部结构,确保不会与 pixel
字段混淆。
struct Pixel;
struct Canvas2;
struct Canvas {
canvas2 : Canvas2,
pixel : Pixel,
}
impl Canvas2 {
fn drawPixel(&mut self, y : usize, x : usize, pixel : &Pixel) {
// Modify internal pixmap using given Pixel description.
}
}
impl Canvas {
fn setPixel(&mut self, y : usize, x : usize) {
// Draw a pixel to internal pixmap using own pixel description.
self.canvas2.drawPixel(y, x, &self.pixel);
}
}