gpt4 book ai didi

rust - 内部可变性与数据隐藏以固定可变借用的引用

转载 作者:行者123 更新时间:2023-11-29 08:07:48 25 4
gpt4 key购买 nike

如果我们运行 this然后我们正确地得到错误“无法分配给不可变字段a.x”。

如果我们删除两个 //注释,并注释掉这一行,然后我们得到错误“无法分配给 & 引用中的数据”。这是有道理的,因为 &mut不提供内部可变性。我们可以重新借一个&A自由地,所以这不能提供可变访问,ala &&mut&& .

如果我们同时删除 //评论和 /* */评论,然后整个事情编译,允许违反我们不变量的错误行 a.x绝不能指向其他任何东西。

pub struct A<'a> {
pub x: &'a mut [u8; 3],
}

fn main() {
let y = &mut [7u8; 3];
let /*mut*/ a = A { x: &mut [0u8; 3] };
a.x[0] = 3;
a.x = y; //// This must be prevented!
{
// let b = &/*mut*/ a;
// b.x[1] = 2;
}
println!("{:?}", a.x);
}

应该如何维护 x 的不变量?不得更改?除了为 A 编写构造函数外,我们可以在提供公共(public)取消引用方法的同时将该字段设为私有(private)。在 Not Acceptable 。

我们可以通过创建 A 来避免讨厌的构造函数包装器的私有(private)成员 struct AA(A)它本身承载公共(public)取消引用方法。现在AA需要一个简单的构造函数,但它不需要 A 的所有字段的参数, 不影响执行顺序等。如果我们需要同时为 A 实现一些特性,这将变得很痛苦。和 AA尽管。

然而,另一种方法是通过使用 Cell<A> 来使用内部可变性, 使用 Cell::replace 访问它, 稍后再放回去。这听起来很有问题,但表明存在更多解决方案。

任何更清洁的方法?

最佳答案

而不是使用 Cell<A>你可以在 A 中创建数组包含 Cell<u8>小号:

use std::cell::Cell;

pub struct A<'a> {
x: &'a [Cell<u8>; 3],
}

fn main() {
// let y = &mut [7u8; 3];
let a = A { x: &[Cell::new(0u8), Cell::new(0u8), Cell::new(0u8)] };
a.x[0].set(3);
// a.x = y;
{
let b = &a;
b.x[1].set(2);
}
println!("{:?}", a.x);
}

这仍然会按照您的要求运行,性能相同,但现在 a变量是不可变的,所以你不能改变 a.x .您也不需要使数组引用可变。

您的示例的轻微缺点是您不能使用数组重复语法,因为 Cell<T>不执行 Copy .这似乎是一个遗漏,但对于为什么是 here 有一些解释。 .

关于rust - 内部可变性与数据隐藏以固定可变借用的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42358738/

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