Rust 带有assert_eq的可变和不可变借用问题

Rust 带有assert_eq的可变和不可变借用问题,rust,Rust,我正在重写一些C测试代码,让LEDDriver生锈 struct LEDDriver<'a> { address: &'a mut u32, } impl<'a> LEDDriver<'a> { fn new(address: &'a mut u32) -> Self { let leddriver = LEDDriver { address: address }; *leddriver.

我正在重写一些C测试代码,让LEDDriver生锈

struct LEDDriver<'a> {
    address: &'a mut u32,
}

impl<'a> LEDDriver<'a> {
    fn new(address: &'a mut u32) -> Self {
        let leddriver = LEDDriver { address: address };
        *leddriver.address = 0;
        leddriver
    }
}

fn driver_init_leds_off() {
    let ref mut addr = 0xffffffff;
    let leddriver = LEDDriver::new(addr);

    assert_eq!(0, *addr);
}
struct-LEDDriver{
fn新(地址:&'a mut u32)->自我{
让leddriver=leddriver{address:address};
*ledriver.address=0;
发光二极管驱动器
}
}
fn驱动程序启动指示灯关闭(){
设ref mut addr=0xffffffff;
让ledriver=ledriver::new(addr);
断言(0,*addr);
}
您可以运行该示例


问题在于assert语句要求ref是不可变的,但我将mut ref传递给LEDDriver以清除addr。

因为这是一个最小化的示例,我不确定它是否符合您的实际用例,但在数据被借用后,您可以使用
*ledriver.address
而不是
*addr
来访问数据(因为
ledriver
是借用数据的人)


您还可以使用
单元格
,这不会产生任何内存或运行时开销,但会阻止对内部值的引用

use std::cell::Cell;

struct LEDDriver<'a> {
    address: &'a Cell<u32>,
}

impl<'a> LEDDriver<'a> {
    fn new(address: &'a Cell<u32>) -> Self {
        let leddriver = LEDDriver { address: address };
        leddriver.address.set(0);
        leddriver
    }
}

fn driver_init_leds_off() {
    let ref mut addr = Cell::new(0xffffffff);
    let leddriver = LEDDriver::new(addr);

    assert_eq!(0, addr.get());
}
使用std::cell::cell;
结构发光二极管驱动器{
fn新(地址:&'a单元)->Self{
让leddriver=leddriver{address:address};
leddriver.address.set(0);
发光二极管驱动器
}
}
fn驱动程序启动指示灯关闭(){
让ref mut addr=Cell::new(0xffffffff);
让ledriver=ledriver::new(addr);
断言(0,addr.get());
}

如果
addr
的内存位置将被传递到硬件或从中断中修改,那么您应该使用
Volatile
,因为否则可以假设多个
addr.get()
之间没有
addr.set()
将产生相同的结果,即使硬件或中断可能改变了它

assert\u eq
放在
leddriver
绑定之上,它也会工作。我在这里看到一个矛盾:你传递了一个可变所有权的引用,当你试图读取它时。这显然是禁止生锈的。如果你已经有了一个可变的引用,你就不能有任何引用。这是借阅检查规则。但是,您可以通过使用智能指针或
Rc
“问题在于assert语句要求ref是不可变的,[…]”真正的问题是您试图使用已传递给
LEDDriver
实例的可变引用,从而导致两个可变引用,这是违法的。我建议您在上再读一读这本书。@ljedrz这将编译,但我需要在LEDDriver初始化后检查引用的值。是否有任何东西反对编写
assert\u eq!(0,*ledriver.address)
Volatile
——是板条箱里的那个吗?是的,就是那个