问题标签 [interior-mutability]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
693 浏览

rust - How does Rayon prevent the use of RefCell, Cell and Rc between threads?

The Rayon documentation say it guarantees that using Rayon APIs will not introduce data races.

How can the compiler know that the method called by the closures is not sharing mutable state, for example RefCell<T> and Cell<T>, or using structs that are not thread-safe, for example Rc<T>?

I understand that core::marker::Sync marks types that are safe to share between threads but I don't understand how the Rayon type declarations and the compiler enforce it!

0 投票
1 回答
130 浏览

data-structures - 安全地返回对内部节点的多个引用,同时仍然允许其他节点的突变

例如,假设我有一个不允许删除节点的链表。

是否可以返回对已插入值的共享引用,同时仍允许更改节点的相对顺序或插入新节点?

只要一次只使用一个节点来改变列表,即使通过其中一个节点的突变也应该是安全的“在纸上”。是否可以在 rust 的所有权系统中表示这一点?

我特别有兴趣在没有运行时开销的情况下这样做(可能在实现中使用 unsafe,但不在接口中使用)。

编辑:根据要求,这是一个示例,概述了我的想法。

换句话说,列表节点内包含的数据被视为可以共享/可变借用的一种资源,节点之间的链接是可以共享/可变借用的另一种资源。

0 投票
2 回答
5375 浏览

data-structures - 有没有办法使不可变引用可变?

我想解决 Rust 中的一个 leetcode 问题(Remove Nth Node From End of List)。我的解决方案使用两个指针来查找Node要删除的:

我借用了链表的两个不可变引用。在找到要删除的目标节点后,我想删除一个并使另一个可变。以下每个代码示例都会导致编译器错误:

我不知道这个解决方案是否可以用 Rust 编写。如果我可以使不可变引用可变,我该怎么做?如果没有,是否有在使借用检查器满意的同时实现相同的逻辑?

0 投票
1 回答
807 浏览

enums - 匹配内部可变枚举的预期方法是什么?

这些是我可以想出的尝试匹配引用计数的内部可变枚举的方法:

操场

然而,大多数方法都会产生类型不匹配的错误,例如

或者

唯一可行的方法是:

这是预期的方式吗?即使是只读访问?

0 投票
1 回答
98 浏览

rust - 如何使用 RAII 属性创建订阅者对象?

我正在通过一个发布者/订阅者模型的链接与一些硬件交谈。在 C++ 中,我使用 RAII 进行订阅以记住始终取消订阅,但我似乎无法在 rust 中获得所有权/借用权。

天真地,这就像我想做的事情。据我了解,send可能receive需要对.&mut selfSubscriptionTransport

这里至少有两个问题。一个是Subscription应该如何保留对它的“父级”的引用Transport,另一个是fn test我不能Transport为两个不同的订阅借两次的问题。

我有一种感觉,我在这里问了一个错误的问题,所以也许有一种完全不同的方式来解决这个问题的好方法?

0 投票
1 回答
89 浏览

rust - 如何在多个“编码器”之间共享可变编写器?

我正在实现一个数据压缩接口:

编码器可以在某种输出中编码一些数字,其中输出可能是流(文件)、字节缓冲区甚至另一个编码器。可能会调用这样的实现:

这一切都很好,但在某些情况下,我需要针对同一个输出流的多个编码器。类似(简化):

在这里,两个编码器将在写入数据时交错数据。

&mut这需要对同一文件进行可变访问,而直接引用则无法做到这一点。据我所知,实现这一点的唯一方法是使用RefCell; 有没有更好的办法?

据我所知,这会使所有编码器实现变得不那么干净。现在可以像这样声明编码器:

使用 a RefCell,每个编码器结构和构造函数都需要处理Rc<RefCell<W>>,这不是很好,并且会将编写器的共享性泄漏到编码器中,而编码器不需要知道编写器是共享的。

(我确实考虑过是否可以更改NumericEncoder特征以采用 writer 参数,这必须是std::io::Write。这不起作用,因为某些编码器不写入 a std::io::Write,而是写入另一个NumericEncoder。)

0 投票
0 回答
262 浏览

tree - 有没有办法避免在创建后不会突变的树中使用 RefCell?

我正在编写一个简短的程序来随机生成一个视频游戏地牢,但是我在干净地创建树中的子地牢时遇到了一些麻烦。

我所拥有的是丑陋的,并且意味着运行时检查借用RefCell,即使树在创建后不需要可变性。

由于它是一棵树,我使用Rc<T>andWeak<T>来分别保存对子节点和父节点的引用。这产生了一个问题,因为子节点的值取决于其父节点的值,因此需要创建父节点以便为其子节点提供父节点引用,而需要创建子节点以向父节点提供其子字段。

如果我使用在父节点之前创建子节点的函数(例如,通过在父节点实例化之前将父字段的相关值传递给它们),它们当然将无法获得对其父节点的引用。

我可以让它工作的唯一方法RefCell是在创建每个节点后使用它们设置子节点,如图所示。

这是每个节点的结构:

这是给定根地牢的用于生成树的函数的概述:

有没有办法以不涉及引入的方式重写它RefCell?树在创建后不需要是可变的,但我想不出任何其他方法来打破父级需要创建子级才能被实例化的循环,但子级也需要父级已经被实例化创建以获取其父引用。

当然,这在普通树中不会成为问题,其中推送到父节点的节点的值通常与父节点的值无关,但我似乎无法找到一个好的 Rust 解决方案来解决像这样的情况.

0 投票
0 回答
35 浏览

rust - 为什么动态闭包(作为特征对象的闭包)在放置 Rc 后变得不可用>?

<Rc<RefCell<T>>由于某种原因,我需要关闭闭包:

  1. 多次引用闭包;
  2. 闭包可以修改环境(内部可变性);
  3. 闭包最好存储为特征对象,因为最终我想将引用放在向量中。

但是,当存储为 trait 对象时,闭包变得不可用。

这是一个例子。简单地说,变量closure不会改变环境。在我自己的用例中,我确实需要 mutate 环境。

我知道如果我删除变量上的类型约束它会起作用closure。但是那样我就失去了在 vec.xml 中放置类似闭包的能力。

有没有办法在后面使用闭包<Rc<RefCell<T>>?或者是否有其他替代方案可以满足我列出的 3 个要求?

0 投票
1 回答
1797 浏览

rust - 为什么 Mutex 被设计为需要 Rust 中的 Arc

如果使用 a 的唯一原因是并发代码(即多线程),为什么Mutex<T>设计需要a?首先将 a 别名为原子引用不是更好吗?我使用https://doc.rust-lang.org/book/ch16-03-shared-state.html作为参考。Arc<T>Mutex<T>Mutex<T>

0 投票
1 回答
5793 浏览

rust - Rc 和有什么不一样> 和 RefCell>?

Rust 文档涵盖了Rc<RefCell<T>>相当广泛的内容,但没有涉及到RefCell<Rc<T>>我现在遇到的 .

这些是否有效地给出了相同的结果?它们之间有重要的区别吗?