使用列表项编辑列表

时间:2016-01-06 07:22:01

标签: rust

我正在对Rust书中的dining philosophers问题进行一些修改。

在书中,他们手动创造了所有的哲学家,最后一个人用左手和右手切换。我以编程方式完成了这项工作(使用我推动哲学家推进的for循环),现在我想修改最终的哲学家。

这就是我想要做的事情

// make the last philosopher left handed (switch forks)
let p = &philosophers[length - 1];
philosophers[length - 1] = Philosopher{left: p.right, right: p.left, name: p.name.clone()};
// error: cannot move out of indexed content [E0507]

这就是我必须要做的事情

philosophers[length - 1] = Philosopher{
   left: philosophers[length - 1].right, 
   right: philosophers[length - 1].left, 
   name: philosophers[length -1].name.clone(),
};

第一个例子没有编译,我无法找到一种方法来编译它而不需要像let p = philosophers[length - 1].clone()那样完全复制数据! (不是我想要的)。

有没有办法更加鲁莽地做到这一点?

2 个答案:

答案 0 :(得分:3)

事实上,你无法改变你正在借用的东西。您可以克隆它 - 您已经克隆了name字段,而leftright仅为usize

假设您的结构包含更多更大的数据,克隆不是一种选择。在这种情况下,有多种可能的解决方案。您可以使用Vec而不是普通数组:首先创建所有4个普通哲学家,然后创建最后一个push。或者您可以使用std::mem::swap来交换leftright

std::mem::swap(&mut philosophers[length - 1].left, &mut philosophers[length - 1].right);

答案 1 :(得分:0)

这个例子很短,以至于恕我直言的原始解决方案(没有循环)更具表现力。但如果你想改变最后一位哲学家,你可以这样做:

let p = &mut philosophers[length - 1];
let left = p.left;
let right = p.right;
p.left = right;
p.right = left;

您将直接操作最后一位哲学家的参考。这样,您不需要克隆他/她的名字,只需交换fork ID。