我是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”实例。
请不要问我为什么要这样做。它是我实际用例的简化版本。我真的很想知道我可以做些什么来使这段代码编译。
最佳答案
根本的问题是,对drawPixel
中的setPixel
的调用使drawPixel
成为pixel
字段的两个别名:一个可变的别名(通过self
(如self.pixel
))和一个不变的别名(通过pixel
参数)。在Rust中,非mut
指针实际上是指向不变值的指针。但是,使用这两个别名,drawPixel
将能够使pixel
参数所引用的像素值发生突变,并且其值会意外更改。
如果Pixel
是小类型(例如RGBA四边形)并且未实现Drop
,则可以将其设置为Copy
,然后按值传递Pixel
(请参阅A.B.'s answer)。
如果不可能,请考虑drawPixel
实际需要突变的内容。是否需要更改pixel
字段?如果是,则需要以某种方式复制像素,否则,当您对字段进行突变时,pixel
参数的值将发生变化,如上所述。在这种情况下,您可能只能实现Clone
并使用clone()
方法来获取像素的副本。
如果不需要在pixel
中对drawPixel
字段进行突变,则可以将您突变的字段移动到一个单独的结构中,然后将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);
}
}
关于compiler-errors - 如何使以下Rust代码编译?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31492071/