什么是在Rust中拥有多个链表并在它们之间移动数据的正确方法?

时间:2017-02-03 18:33:09

标签: vector reference linked-list rust borrow-checker

有多个std::collections::LinkedList的正确方法是什么,这些列表的编号在编译时是未知的?

我正在填充数据并合并它们(例如使用append())。 我认为有一个包含这些列表的向量,或者包含对这些列表的引用会很好。

我尝试了以下内容:

use std::collections::LinkedList;

fn listtest() {
    let mut v: Vec<LinkedList<i32>> = Vec::new();
    v.push(LinkedList::new()); // first list
    v.push(LinkedList::new()); // second list
    v[0].push_back(1); // fill with data
    v[1].push_back(3); // fill with data
    v[0].append(&mut v[1]); // merge lists
}

fn main() {
    listtest();
}

这无法编译,因为在使用v时我有append()的两个可变引用。我也尝试使用Vec<&mut LinkedList<i32>>,但没有成功。

解决这个问题的正确方法是什么?

2 个答案:

答案 0 :(得分:5)

没有正确方法。一种可能性是使用split_at_mut。这会创建两个单独的切片,每个切片可以与另一个切换:

use std::collections::LinkedList;

fn main() {
    let mut v = vec![LinkedList::new(), LinkedList::new()];
    v[0].push_back(1);
    v[1].push_back(3);

    {
        let (head, tail) = v.split_at_mut(1);
        head[0].append(&mut tail[0]);
    }

    println!("{:?}", v);
}

请参阅:

答案 1 :(得分:2)

大多数集合都有一个iter_mut方法,该方法返回一个迭代器,该迭代器产生对集合中每个项目的可变引用。这些引用都可以同时使用! (但引用必须来自同一个迭代器;你不能同时使用来自iter_mut的单独调用的引用。)

use std::collections::LinkedList;

fn listtest() {
    let mut v: Vec<LinkedList<i32>> = Vec::new();
    v.push(LinkedList::new()); // first list
    v.push(LinkedList::new()); // second list
    v[0].push_back(1); // fill with data
    v[1].push_back(3); // fill with data
    let mut vi = v.iter_mut();
    let first = vi.next().unwrap();
    let second = vi.next().unwrap();
    first.append(second); // merge lists
}

fn main() {
    listtest();
}

还要记住,迭代器使用nth方法在循环中执行等效的next