Rust 如何找到无别名的数据结构
我在和铁锈的最后一个老板,借钱人对抗。这是我正在开发的Rust 如何找到无别名的数据结构,rust,borrow-checker,Rust,Borrow Checker,我在和铁锈的最后一个老板,借钱人对抗。这是我正在开发的mio无功网络应用程序的简化版本。我花了太多时间为手头的任务找到合适的数据结构。我想在遍历能够接受新连接的侦听套接字时注册连接 请参阅以下代码,或在上进行检查HashMap::get_mut在self的1个字段中返回一个唯一的借用到1的值,因此我无法将self传递到Thing::act。我理解为什么会发生这种情况,以及如何导致运行时问题,但不知道如何重构数据结构以避免此类问题 use std::collections::HashMap; t
mio
无功网络应用程序的简化版本。我花了太多时间为手头的任务找到合适的数据结构。我想在遍历能够接受新连接的侦听套接字时注册连接
请参阅以下代码,或在上进行检查HashMap::get_mut
在self
的1个字段中返回一个唯一的借用到1的值,因此我无法将self
传递到Thing::act
。我理解为什么会发生这种情况,以及如何导致运行时问题,但不知道如何重构数据结构以避免此类问题
use std::collections::HashMap;
trait ThingSet {
fn register(&mut self, thing: Box<Thing>);
}
trait Thing {
fn act(&mut self, reg: &mut ThingSet);
}
struct Stream;
impl Thing for Stream {
fn act(&mut self, reg: &mut ThingSet) {}
}
struct Listener;
impl Thing for Listener {
fn act(&mut self, reg: &mut ThingSet) {
if true {
let mut stream = Stream {};
reg.register(Box::new(stream));
}
}
}
struct Loop {
next: usize,
things: HashMap<usize, Box<Thing>>,
}
impl Loop {
fn new() -> Loop {
Loop { next: 1, things: HashMap::new(), }
}
fn run(&mut self) {
let mut needs_action = Vec::<&mut Box<Thing>>::new();
{
// modeling a connection on one of the listeners...
if let Some(t) = self.things.get_mut(&1usize) {
needs_action.push(t);
}
}
for t in needs_action {
t.act(self as &mut ThingSet);
}
}
}
impl ThingSet for Loop {
fn register(&mut self, thing: Box<Thing>) {
self.things.insert(self.next, thing);
self.next += 1;
}
}
fn main() {
let mut l = Loop::new();
let mut p1 = Listener {};
let mut p2 = Listener {};
l.register(Box::new(p1));
l.register(Box::new(p2));
l.run();
}
使用std::collections::HashMap;
特征集{
fn寄存器(&mut self,thing:Box);
}
特质事物{
fn act(&mut self,reg:&mut ThingSet);
}
结构流;
为流执行任务{
fn act(&mut self,reg:&mut ThingSet){}
}
结构侦听器;
给听者的暗示{
fn act(&mut self,reg:&mut ThingSet){
如果是真的{
让mut stream=stream{};
注册寄存器(框::新(流));
}
}
}
结构循环{
下一步:使用,
事物:HashMap,
}
impl环路{
fn new()->循环{
循环{next:1,things:HashMap::new(),}
}
fn运行(&mut self){
let mut needs_action=Vec:::new();
{
//正在其中一个侦听器上建模连接。。。
如果让一些(t)=自我。事物。获取更多(&1U大小){
需要动作。推(t);
}
}
在需要行动的时候{
t、 act(自身组件和多组件组件);
}
}
}
循环的impl ThingSet{
fn寄存器(&mut self,thing:Box){
self.things.insert(self.next,thing);
self.next+=1;
}
}
fn main(){
让mut l=Loop::new();
设mutp1=Listener{};
设mutp2=Listener{};
l、 寄存器(框::新(p1));
l、 寄存器(框::新(p2));
l、 run();
}
我可以找到很好的教程来解释借阅检查器的功能以及它不允许的功能。我找不到关于如何找到可以避免不允许引用的替代数据结构的好教程
你能给我一些建议如何重新设计这个特定的问题吗?我认为可以纠正这个特定的问题,但我觉得这里可能有一个更普遍的问题。如果我错了,请纠正我,但您运行
循环::run
它将扫描您的内容集
,然后根据某种条件在需要操作
缓冲区上放置一个对事物的可变引用。这里的一般问题似乎是,通过不同的迭代,rustc无法验证这些不同的调用是否会为同一元素提供不同的可变引用或另一个可变引用。因此,您可以使用类似于RefCell
(请参阅Jsor的答案)的方法强制执行运行时借用检查,或者您可以从ThingSet
中获取所有权,并用其他内容替换您所获取的内容,或者将元素一起从集合中移除
例如,获取元素的所有权并将其从ThingSet
中删除,如下所示:
impl Loop {
fn new() -> Loop {
Loop { next: 1, things: HashMap::new(), }
}
fn run(&mut self) {
let mut needs_action = Vec::<Box<Thing>>::new();
// modeling a connection on one of the listeners...
if let Some(t) = self.things.remove(&1usize) {
needs_action.push(t);
}
for t in &mut needs_action {
t.act(self as &mut ThingSet);
}
}
}
impl循环{
fn new()->循环{
循环{next:1,things:HashMap::new(),}
}
fn运行(&mut self){
let mut needs_action=Vec:::new();
//正在其中一个侦听器上建模连接。。。
如果让一些(t)=自。事物。移除(&1U大小){
需要动作。推(t);
}
对于t in&mut,需要采取行动{
t、 act(自身组件和多组件组件);
}
}
}
这是一个选项,但我认为与其使用替换
,不如使用从哈希映射中删除,必要时重新插入。是的,我可能应该更改它。好的,这里的想法是,使用此数据结构不可能进行静态分析,因此,Rc
将使用运行时检查提供相同的安全性。@wigy不是说静态分析不可能,而是Rust的借阅检查器无法区分数据结构中的框(或任何其他拥有的指针)和平面结构。出于某种原因,@Jsor删除了他的帖子,但他有两个很好的理由:我会在周末之前接受@breeden的答案,除非有人提出一个数据结构,允许对这个用例进行静态借用检查。我删除了它,因为在不安全的解决方案中,如果你从另一个侦听器的需要行动
中删除一个条目,它会导致在空闲后使用act
。还有她