我是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/

10-09 01:08