mem ::替换为Rust

时间:2014-11-29 01:28:50

标签: memory iterator rust

示例指南生锈显示了带有迭代器的斐波纳契数列的以下代码here

fn next(&mut self) -> Option<u32> {
    let new_next = self.curr + self.next;
    let new_curr = mem::replace(&mut self.next, new_next);

    // 'Some' is always returned, this is an infinite value generator
    Some(mem::replace(&mut self.curr, new_curr))
}

我想了解这是什么优势,而不是最直观的(如果你来自其他语言):

fn next(&mut self) -> Option<u32> {
    let tmp = self.next;
    self.next = self.curr + self.next;
    self.curr = tmp;
    Some(self.curr)
}

1 个答案:

答案 0 :(得分:12)

由于Rust的所有权,并不总是可以编写直接代码。如果self.next存储非Copy类型(例如Vec<T>适用于任何类型T),那么let tmp = self.next;会从self中取出该值按值,即移动所有权,因此源不应该可用。但是源代码在引用后面,引用必须始终指向有效数据,因此编译器不能允许移出&mut:您会收到cannot move out of dereference of `&mut`-pointer之类的错误。

replace通过unsafe代码绕过这些问题,通过内部保证任何失效在replace返回时完全有效。

您可以查看this answer以获取有关移动的更多信息,this question查看有关swap功能的相关问题(replace implemented使用the standard library's swap内部{{3}}。