问题标签 [refcell]

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 投票
0 回答
42 浏览

rust - rust 内部可变性示例代码改进

我正在尝试学习 rust internal mutability 的一些基本概念。并尝试实现一个树状数据结构示例:

    1. 每个节点都有一个父节点。
    1. 每个节点都有一些子节点。
    1. 从每个节点我可以更改父节点和所有子节点,不仅是节点的数量,还有一些节点属性。
    1. 没有循环参考问题。

我写的代码列表如下,但有点难看,可能有一些性能问题。所以问题是如何提高代码质量。欢迎任何建议。

输出是:

0 投票
2 回答
139 浏览

rust - RefCell 是从向量中借用两个可变元素的适当解决方法吗?

考虑这个“战斗”两个随机“玩家”的玩具示例:

此代码将不起作用,因为该fight函数需要对同一players向量的元素进行两个可变引用。

我丑陋的解决方法目前如下所示,使用RefCell

我想知道是否有更有效的方法来避免额外的开销RefCell?我可以split_at_mut以某种方式利用吗?

0 投票
0 回答
177 浏览

rust - 如何使用 Rc 和 RefCell 修改对同一结构中字段的引用?

我有一个结构体,它的字段引用了同一结构体中数组上的当前元素,使用Rc. 我现在可以引用 thennums字段中的任何元素:

操场

当我尝试修改时出现问题cur_num,因为我希望它在nums数组上反映它的值。每当我尝试通过取消引用它来做到这一点时,它似乎只会改变cur_num.

为什么我不能在同一个结构中存储一个值和对该值的引用?是关于将值存储在同一个结构中的另一个主题,但答案没有显示可以移动值的情况,或者RefCell.

有没有办法修改它,RefCell以便我可以修改参考?

0 投票
1 回答
384 浏览

rust - Rc Refcell 的变异字段取决于其其他内部字段

我需要遍历 Rc RefCell 中结构的一个字段,并根据其其他字段修改它的一些参数。例如对于结构 Foo:

以下代码恐慌:

我可以通过在可变借用之前克隆 foo1 并仅在闭包内使用克隆来解决它,但这会导致不必要的复制。事实上,我基本上需要一个对 foo2 的可变引用和一个对 foo1 的不可变引用(请注意,这是简化的代码,此处无法压缩迭代器)。我知道代码不符合借用规则。有没有办法在不克隆数据的情况下让它工作?

0 投票
3 回答
201 浏览

rust - 如何将*可选*引用返回到 RefCell 内容

我有一种将其数据存储在 a 后面的容器中的类型,该容器Rc<RefCell<>>大部分对公共 API 隐藏。例如:

但是,查看容器内部需要返回一个Ref. 这可以使用Ref::map()- 例如:

但是,我想要一个不惊慌失措的peek, 会返回Option<Ref<'_, Value>>. 这是一个问题,因为Ref::map要求您返回对 内部存在的东西的引用RefCell,所以即使我想 return Ref<'_, Option<Value>>,它也不起作用,因为返回的选项storage.get()是短暂的。

尝试使用从以前查找的密钥Ref::map创建一个Ref也不会编译:

有效的方法是执行两次查找,但这是我真正想避免的事情:

操场上的可编译示例。

像这样的相关问题假设内部参考总是可用的,所以他们没有这个问题。

我发现Ref::filter_map()哪个可以解决这个问题,但它还没有稳定版,而且还不清楚它离稳定还有多远。除非有其他选择,否则我会接受一个使用的解决方案,unsafe只要它是健全的并且依赖于书面保证。

0 投票
1 回答
120 浏览

rust - 如何从 std::Rc 的向量实现迭代器> 智能指针?

我试图了解如何使用内部可变性。这个问题与我之前的问题密切相关。

我有一个通用结构Port<T>,它拥有一个Vec<T>. 我们可以将端口 B“链接”到端口 A,因此,在读取端口 A 的内容时,我们可以读取端口 B 的内容。但是,这种链接对端口 A 的阅读器是隐藏的。这就是我实现该iter(&self)方法的原因:

该应用程序具有以下伪代码行为:

  • 创建端口
  • 环形:
    • 用值填充端口
    • 连锁港口
    • 迭代端口的值
    • 清除端口

main函数应如下所示:

但是,编译器抱怨:

我一直在阅读几篇文章等,看来我需要合作Rc<RefCell<Port<T>>>才能改变端口。我改变了实现Port<T>

这也不编译:

我想我知道问题出在哪里:p.borrow()返回对被链接的端口的引用。我们使用该引用来创建迭代器,但是一旦函数完成,引用就会超出范围并且迭代器不再有效。

我不知道如何处理这个问题。我设法实现了以下不安全的方法:

虽然这可行,但它使用了不安全的代码,并且必须有一个安全的解决方法。

我为我的应用程序的更多细节设置了一个游乐场。应用程序编译并输出预期的结果(但使用了不安全的代码)。

0 投票
1 回答
84 浏览

rust - 在 Rust 中一次从全局哈希图中访问两个可变引用

假设我们有一个使用lazy_static :制作的特征对象的全局可访问哈希图MY_ANIMALS: Mutex<HashMap<i32, AnimalBox>>,其中type AnimalBox = Box<dyn AnimalExt+Send>

现在,我们希望这个全局哈希图中的动物能够相互交互。例如,一个AnimalBox可以AnimalExt::eat(&mut self, prey: &mut AnimalBox)另一个。

问题是我们的eat()函数既需要对 self 的可变引用,也需要对祈祷的可变引用(因为我们希望AnimalExt::perish(&mut self)当它被吃掉时,祈祷会指向它。

但是,获得两个对我们的 hashmap 的可变引用会导致WouldBlock错误:

有什么好的解决方法吗?或者没有安全的方法可以使用哈希图来做到这一点?我已经看到了类似问题的答案,但建议的答案建议使用RefCell,这与lazy_static 的Send特征要求不兼容。

0 投票
2 回答
111 浏览

rust - 参考单元> 不变

这是我的简化代码。我需要更改函数中的 pdp_state。但状态仍然是'a'。我不明白为什么克隆 Rc 不起作用。我还检查了这个克隆的结构,它工作正常。

更新:我的 set 函数看起来像这样。我需要两个可以访问 pdp_state 的闭包。我将这些闭包作为回调传递。我确信这些关闭不会一起调用。

0 投票
1 回答
95 浏览

rust - 哈希特征不适用于 Rc> 在枚举中

我手动为它定义了一个结构MyData和实现PartialEqHash特征。

我定义了一个包含Rc<MyData>and的枚举Rc<RefCell<MyData>>

我想为枚举派生PartialEqHash,但失败了:

  1. PartialEq和两者Hash都适用于Rc<MyData>;
  2. PartialEq作品Rc<RefCell<MyData>>也适用;
  3. Hash不适用Rc<RefCell<MyData>>

我有两个问题:

  1. 为什么?为什么只有Hash不只适用于Rc<RefCell<MyData>>

  2. 如何解决?

    我无法实现Hashfor Rc<RefCell<MyData>>。在四处搜索后,我找到了一种方法:定义一个新的包装器结构,like struct RRWrapper<T> (Rc<RefCell<T>>),然后Hash为此实现RRWrapper。但这会带来很多代码。有没有惯用的方法?我认为这是一个普遍的用法。

预先感谢,

PS:在我程序的真实代码中,只有Rc<RefCell<MyData>>枚举中没有Rc<MyData>. 我放在Rc<MyData>这里只是为了比较。PS2:在我程序的真实代码中,枚举中不止一个Rc<RefCell<T>>


原始源代码:

错误:

源代码struct RRWrapper

0 投票
1 回答
60 浏览

dynamic - 如何在 Rc 中投射具体对象> 到动态特征对象?

我有MyText实现ModifyValue特征的结构。MyText::new返回Rc<RefCell<MyText>>

我想要一个结构Modifier,给定一个类型的 jet Rc<RefCell<dyn ModifyValue>>(实际上是任何实现 trait 的动态对象ModifyValue),知道如何调用modify给定对象的方法。

它给出了一个错误,我不能txt用它的特性动态地挂钩对象。:

如果我删除两个有问题的行,代码就可以工作。

在 C++ 中,我会使用纯虚拟类来执行此操作,但我无法在 Rust 中重现它(尤其是使用Rc.