2014-07-21 10 views
7

Chciałbym wziąć plastry zmienne i skopiować zawartość na dwa nowe plasterki. Każdy kawałek jest połową oryginału.Jak utworzyć dwa nowe plasterki z jednym plasterkiem?

Moja próba nr 1:

let my_list: &mut [u8] = &mut [0, 1, 2, 3, 4, 5]; 
let list_a: &mut [u8] = my_list[0..3].clone(); 
let list_b: &mut [u8] = my_list[3..6].clone(); 
println!("{:?}", my_list); 
println!("{:?}", list_a); 
println!("{:?}", list_b); 

wyjściowa:

error: no method named `clone` found for type `[u8]` in the current scope 
--> src/main.rs:3:43 
    | 
3 |  let list_a: &mut [u8] = my_list[0..3].clone(); 
    |           ^^^^^ 

error: no method named `clone` found for type `[u8]` in the current scope 
--> src/main.rs:4:43 
    | 
4 |  let list_b: &mut [u8] = my_list[3..6].clone(); 
    |           ^^^^^ 

Moja próba # 2:

let my_list: &mut [u8] = &mut [0, 1, 2, 3, 4, 5]; 
let list_a: &mut [u8] = my_list[0..3].to_owned(); 
let list_b: &mut [u8] = my_list[3..6].to_owned(); 
println!("{:?}", my_list); 
println!("{:?}", list_a); 
println!("{:?}", list_b); 

wyjściowa:

error[E0308]: mismatched types 
    --> src/main.rs:12:29 
    | 
12 |  let list_a: &mut [u8] = my_list[0..3].to_owned(); 
    |        ^^^^^^^^^^^^^^^^^^^^^^^^ expected &mut [u8], found struct `std::vec::Vec` 
    | 
    = note: expected type `&mut [u8]` 
       found type `std::vec::Vec<u8>` 
    = help: try with `&mut my_list[0..3].to_owned()` 

error[E0308]: mismatched types 
    --> src/main.rs:13:29 
    | 
13 |  let list_b: &mut [u8] = my_list[3..6].to_owned(); 
    |        ^^^^^^^^^^^^^^^^^^^^^^^^ expected &mut [u8], found struct `std::vec::Vec` 
    | 
    = note: expected type `&mut [u8]` 
       found type `std::vec::Vec<u8>` 
    = help: try with `&mut my_list[3..6].to_owned()` 

mogę użyć dwóch Vec<u8> i tylko pętlę nad wejściem i wcisnąć sklonowane wartości Chyba, ale miałem nadzieję tam był ładniejszy sposób, aby to zrobić:

extern crate rand; 

use rand::{thread_rng, Rng}; 

fn main() { 
    let my_list: &mut [u8] = &mut [0; 100]; 
    thread_rng().fill_bytes(my_list); 
    let list_a = &mut Vec::new(); 
    let list_b = &mut Vec::new(); 
    for i in 0..my_list.len() { 
     if i < my_list.len()/2 { 
      list_a.push(my_list[i].clone()); 
     } else { 
      list_b.push(my_list[i].clone()); 
     } 
    } 
    println!("{:?}", list_a.as_slice()); 
    println!("{:?}", list_b.as_slice()); 
    println!("{:?}", my_list); 
} 

Odpowiedz

5

Można budować wektorów z plasterków bezpośrednio przez klonowanie elementów za pomocą wielu metod:

  1. Vec::to_vec
  2. From/Into
  3. ToOwned
fn main() { 
    let my_list: &mut [u8] = &mut [0, 1, 2, 3, 4, 5]; 
    let mut vec1 = my_list[0..2].to_vec(); 
    let mut vec2: Vec<u8> = my_list[2..4].into(); 
    let mut vec3 = my_list[2..6].to_owned(); 

    println!("{:?}", vec1); 
    println!("{:?}", vec2); 
} 

Twój oryginalny problem został spowodowany ponieważ wszystkie te zwracają Vec ale próbowali twierdzą, że był to kawałek, co odpowiada:

let thing: &mut [u8] = Vec::new(); 
+0

Miło, nie zdawałem sobie sprawy, że ta funkcja istnieje. –

+0

Niezły, zdecydowanie najczystszy, jaki widziałem do tej pory. Czy jest jakaś wada przy korzystaniu z Vec vs & [] lub & mut []? Oczywiście Vec jest łatwiejszy w obsłudze, ale wydaje się, że może być trochę narzut. – user439299

+1

Plasterek jest tylko reprezentacją, jeśli wywołasz as_slice(), pożyczy referencję do wektora, ale nie stworzy nowego. W razie wątpliwości sprawdź parametry życia (http://doc.rust-lang.org/std/vec/struct.Vec.html#method.as_slice), ma to samo żywotność co wektor. – snf

2

mógł łańcuch można dwa iteratory ciągu plasterki.

let my_list: &mut [u8] = &mut [0, 1, 2, 3, 4, 5]; 
let mut slices = my_list[0..3].iter().chain(my_list[3..6].iter()); 
for e in slices {} 

chain będzie iteracyjnego pierwszą iterację, a następnie drugi.

Aby utworzyć nowe listy:

let my_list: &mut [u8] = &mut [0, 1, 2, 3, 4, 5]; 
let mut a: Vec<u8> = my_list[0..3].iter().cloned().collect(); 
let mut b: Vec<u8> = my_list[3..6].iter().cloned().collect(); 
+0

Czy pętla nad plasterkami różni się od pętli nad my_list? Próbuję znaleźć dwie nowe listy oprócz oryginału. – user439299

+0

Jeśli chcesz tworzyć nowe listy, utwórz dwa wektory. Plastry to tylko widok na jakiś wektor. –

+0

Otrzymuję to, gdy próbuję łańcuch iter() i slice(): ** nie udało się znaleźć implementacji rdzenia cechy :: iter :: FromIterator dla & mut [u8] ** ... EDYCJA: nvm zapomniałem dodać Vec user439299

10

split_at i split_at_mut metody dadzą dwa plasterki, które można następnie skopiować, a nawet bezpiecznie używać bez kopiowania, jeśli pozwala na to narzędzie sprawdzające wypożyczenie.

let (list_a, list_b) = my_list.split_at_mut(my_list.len()/2) 
Powiązane problemy