2017-02-03 5 views
2

Каков правильный способ иметь несколько std::collections::LinkedList s, где количество этих списков неизвестно во время компиляции?Каков правильный способ иметь несколько связанных списков и перемещать данные между ними в Rust?

Я заполняю их данными, а также их слияние (например, используя 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>>, но не удалось.

Каким будет правильный подход к этой проблеме?

ответ

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); 
} 

См:

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 в цикле ,

Смежные вопросы