更改对内部结构的引用,或者是否可以更改 rust 中引用的引用

问题描述 投票:0回答:1

我目前正在尝试将 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...
}
pointers rust mutable-reference
1个回答
0
投票

您可以通过使用指针作为参数而不是引用来完成同样的事情。由于参数和接收器的求值顺序,您必须在调用之前转换为指针,并且无法在参数列表中执行此操作,但这是有效的:

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)
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.