我目前正在尝试将 C 程序转换为 Rust。
C 程序具有以下结构(归结为 MRE):
typedef struct {
bool isActive;
uint32_t value;
} tMyInnerStruct;
typedef struct {
tMyInnerStruct inner1;
tMyInnerStruct inner2;
} tMyStruct;
在函数中我会执行以下指针魔术:
void myFunction()
{
tMyStruct myStruct = initMyStuct();
tMyInnerStruct *pActiveInner = &myStruct.inner1;
// Do something with pActiveInner (pointing to inner1), like setting value...
changeActiveStruct(&myStruct, &pActiveInner);
// Do something with pActiveInner (pointing to inner2), like setting value...
}
void changeActiveStruct( tMyStruct *pMyStruct, tMyInnerStruct **ppActiveInner )
{
if ( &pMyStruct->inner1 == *ppActiveInner ) {
*ppActiveInner = &pMyStruct->inner2;
} else {
*ppActiveInner = &pMyStruct->inner1;
}
}
不,我的问题是:我如何在 Rust 中实现同样的目标?
到目前为止我在 Rust 中尝试过的:
#[derive(Default)]
struct MyInnerStruct {
is_active: bool,
value: u32,
}
#[derive(Default)]
struct MyStruct {
inner1: MyInnerStruct,
inner2: MyInnerStruct,
}
impl MyStruct {
fn change_active(&mut self, active: &InnerTest) -> &mut InnerTest {
if &self.inner1 as *const _ == active as *const _ {
&mut self.inner2
} else {
&mut self.inner1
}
}
}
fn main() {
let mut my_struct: MyStruct = Default::default();
let mut active = &mut my_struct.inner1;
active = my_struct.change_active(active);
// The above complains, that my_struct cannot be borrowed mutable more than once...
}
您可以通过使用指针作为参数而不是引用来完成同样的事情。由于参数和接收器的求值顺序,您必须在调用之前转换为指针,并且无法在参数列表中执行此操作,但这是有效的:
impl MyStruct {
fn change_active(&mut self, active: *const MyInnerStruct) -> &mut MyInnerStruct {
if &self.inner1 as *const _ == active {
&mut self.inner2
} else {
&mut self.inner1
}
}
}
fn main() {
let mut my_struct: MyStruct = Default::default();
let mut active = &mut my_struct.inner1;
active = {
let active = active as *const _;
my_struct.change_active(active)
};
}