gpt4 book ai didi

Change reference to inner struct, or is it possible to change the reference of a reference in rust(将引用更改为内部结构,或者是否可以更改Ruust中引用的引用)

转载 作者:bug小助手 更新时间:2023-10-27 20:00:42 33 4
gpt4 key购买 nike



I'm currently trying to translate a C program to Rust.

我目前正在尝试将一个C程序翻译成Rust。


The C programm has following structures (boiled down to MRE):

C程序具有以下结构(归结为MRE):


typedef struct {
bool isActive;
uint32_t value;
} tMyInnerStruct;

typedef struct {
tMyInnerStruct inner1;
tMyInnerStruct inner2;
} tMyStruct;

and in a function I would do the following pointer magic:

在一个函数中,我将执行以下指针魔术:


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;
}
}

No my question is: How would I achieve the same in Rust?

不,我的问题是:我将如何在铁锈中实现同样的目标?


What I've tried so far in 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: &MyInnerStruct) -> &mut MyInnerStruct {
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...
}

更多回答
优秀答案推荐

You can accompilsh the same thing by using a pointer as argument instead of a reference. Because of the order that arguments and the receiver are evaluated in, you have to convert to a pointer ahead of the call and can't do it in the parameter list but this works:

您可以通过使用指针作为参数而不是引用来编译相同的内容。由于参数和接收器的求值顺序,您必须转换为调用之前的指针,并且不能在参数列表中这样做,但这是可行的:


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)
};
}

Playground

操场




Minor detail, change_active does no longer seem like an apropriate name since the Rust version doesn't actually change active maybe new_active or something else still is a better name for the method

次要细节,CHANGE_ACTIVE看起来不再像是一个合适的名称,因为Rust版本实际上不会更改ACTIVE可能是NEW_ACTIVE或其他名称仍然是该方法的更好名称


更多回答

Thanks, this is what I was searching for :-) The cast during the comparison was already a hint, but I'm not so familiar with the pointers in Rust. The only drawback in my opinion, is the scoped shadowing of the active variable, as it's not a one-liner ;-)

谢谢,这就是我正在寻找的:-)对比过程中的演员阵容已经是一个提示,但我对《铁锈》中的指针不是很熟悉。在我看来,唯一的缺点是活动变量的作用域跟踪,因为它不是一行程序;-)

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com