gpt4 book ai didi

rust - 使用类似 `Copy` 的语义在可变引用上创建包装器

转载 作者:行者123 更新时间:2023-12-03 11:29:56 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Is it possible to create a wrapper around an &mut that acts like an &mut

(1 个回答)



Why is the mutable reference not moved here?

(4 个回答)


1年前关闭。




我一直在修改我写的一些旧代码,其中一个有以下(简化):

pub fn a(x: &mut i32) {
for i in 0..10 {
b(x);
}
}

pub fn b(_x: &mut i32) {

}

效果很好,即使 &mut i32不是 Copy .

我想限制可以在基础类型上调用哪些方法(而不是 &mut i32 我有一些类似于 &mut Vec<...> 的东西),所以我在可变引用上创建了一个包装器类型:

#[derive(Debug)]
pub struct I32RefMut<'a>(&'a mut i32);

我试图重写 ab使用这个包装如下:

pub fn a2(x: I32RefMut) {
for _i in 0..10 {
b2(x);
}
}

pub fn b2(_x: I32RefMut) {

}

这给出了以下错误
17 | pub fn a2(x: I32RefMut) {
| - move occurs because `x` has type `I32RefMut<'_>`, which does not implement the `Copy` trait
18 | for _i in 0..10 {
19 | b2(x);
| ^ value moved here, in previous iteration of loop


Playground link

这是可以理解的,如 x移入 b2在循环的第一次迭代中。

不幸的是,我无法实现 Clone也不是 Copy ,因为一次可能只有 1 个对该对象的可变引用。

我的问题是 &mut i32解决此问题以及如何在我的类型 I32RefMut 上实现此解决方法(或类似方法) .

如果可能的话,我想尽可能避免不安全的代码,比如使用 #[repr(transparent)] struct I32Wrapper(i32)然后转化 &mut i32&mut I32Wrapper ,除非已经存在此类操作的安全包装器。

编辑:

找到了一个“hack”解决方案,但我对它的外观不太满意,所以我将把这个问题留着。如果没有找到其他解决方案,我会将其发布为答案。

如果调用 b2改为 b2( I32RefMut(x.0) ) ,则编译成功。然而, 不能推广到这样的函数:

impl<'a> I32RefMut<'a> {
pub fn my_clone<'b: 'a>(&'b mut self) -> I32RefMut<'b> {
I32RefMut( self.0 )
}
}

当我们尝试调用它时,编译器告诉我们不能借用 x可变两次。

由于此包装器类型应该在库中定义,因此我无法公开它的内部引用,因为包装器的全部目的是限制用户可以在引用上调用的内容。

最佳答案

问题是您在调用 b 时获得了新类型实例的所有权。 .只需引用您的类型即可访问底层类型:

pub fn a2(x: &I32RefMut) {
for _i in 0..10 {
b2(x);
}
}

pub fn b2(_x: &I32RefMut) {

}

Playground

实际上,如果你想改变它,你需要和他们一起玩一下:
pub fn a2(mut x: I32RefMut) {
for _i in 0..10 {
b2(&mut x);
}
}

pub fn b2(_x: &mut I32RefMut) {
*(_x.0) += 1
}

Playground

关于rust - 使用类似 `Copy` 的语义在可变引用上创建包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62316863/

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