Rust 带有assert_eq的可变和不可变借用问题
我正在重写一些C测试代码,让LEDDriver生锈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.
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
——是板条箱里的那个吗?是的,就是那个