2016-10-20 47 views
6

Chcę wziąć x pierwszy i ostatni element z wektora i połączyć je. Mam następujący kod:Jak połączyć dwa plasterki w Rust?

fn main() { 
    let v = (0u64 .. 10).collect::<Vec<_>>(); 
    let l = v.len(); 
    vec![v.iter().take(3), v.iter().skip(l-3)]; 
} 

To daje mi błąd

error[E0308]: mismatched types 
--> <anon>:4:28 
    | 
4 |  vec![v.iter().take(3), v.iter().skip(l-3)]; 
    |       ^^^^^^^^^^^^^^^^^^ expected struct `std::iter::Take`, found struct `std::iter::Skip` 
<anon>:4:5: 4:48 note: in this expansion of vec! (defined in <std macros>) 
    | 
    = note: expected type `std::iter::Take<std::slice::Iter<'_, u64>>` 
    = note: found type `std::iter::Skip<std::slice::Iter<'_, u64>>` 

Jak mogę dostać vec z 1, 2, 3, 8, 9, 10? Używam Rust 1.12.

Odpowiedz

3

Należy collect() wyniki take() i extend() je z collect() wyników ed skip():

let mut p1 = v.iter().take(3).collect::<Vec<_>>(); 
let p2 = v.iter().skip(l-3); 

p1.extend(p2); 

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

Edit: jak Neikos powiedział, że nie trzeba nawet zbierać wynik skip() , ponieważ extend() przyjmuje argumenty implementujące IntoIterator (które ma Skip, ponieważ jest to Iterator).

Edycja 2: twoje liczby są nieco poza; w celu uzyskania 1, 2, 3, 8, 9, 10 należy zadeklarować v następująco:

let v = (1u64 .. 11).collect::<Vec<_>>(); 

Od Range zostaje zamknięty i prawym otwarte.

+0

Dzięki. Czy "<_>" oznacza coś w stylu "proszę podać typ"? –

+2

Nie musisz zbierać 'Pomiń', ponieważ' extend' może przyjmować iterator – Neikos

+0

@TheUnfunCat Tak, '_' jest typem zastępczym – Neikos

9

Po pierwsze, początkowa definicja sekwencji jest błędna. Mówisz, że chcesz 1, 2, 3, 8, 9, 10 jako wyjście, tak to powinno wyglądać:

let v = (1u64 .. 11).collect::<Vec<_>>(); 

Następnie mówisz chcesz złączyć plasterki, więc niech faktycznie używać plastrów:

let head = &v[..3]; 
    let tail = &v[l-3..]; 

Na to punkt, to naprawdę zależy od tego, które podejście lubisz najbardziej. Można włączyć te plastry do iteratorów, łańcuch, następnie zebrać ...

let v2: Vec<_> = head.iter().chain(tail.iter()).collect(); 

... albo zrobić vec i przedłużyć go bezpośrednio plasterki ...

let mut v3 = vec![]; 
    v3.extend_from_slice(head); 
    v3.extend_from_slice(tail); 

... lub rozszerzyć przy użyciu bardziej ogólnych iteratory (co stanie się w przyszłości równoważne ze specjalizacji, ale nie wierzę, że jest tak skuteczny tylko jeszcze) ...

let mut v4: Vec<u64> = vec![]; 
    v4.extend(head); 
    v4.extend(tail); 

... albo cou Używaj Vec::with_capacity i w pętli lub wykonaj połączenie z iteratorem, ale używając extend ... ale muszę się zatrzymać pod adresem o numerze.

Pełna przykładowy kod:

fn main() { 
    let v = (1u64 .. 11).collect::<Vec<_>>(); 
    let l = v.len(); 

    let head = &v[..3]; 
    let tail = &v[l-3..]; 

    println!("head: {:?}", head); 
    println!("tail: {:?}", tail); 

    let v2: Vec<_> = head.iter().chain(tail.iter()).collect(); 
    println!("v2: {:?}", v2); 

    let mut v3 = vec![]; 
    v3.extend_from_slice(head); 
    v3.extend_from_slice(tail); 
    println!("v3: {:?}", v3); 

    // Explicit type to help inference. 
    let mut v4: Vec<u64> = vec![]; 
    v4.extend(head); 
    v4.extend(tail); 
    println!("v4: {:?}", v4); 
} 
+1

' extend() 'powinno wkrótce być wyspecjalizowane w' extend_from_slice() '; zostało scalone kilka dni temu: [Specialise Vec :: extend to Vec :: extend_from_slice] (https://github.com/rust-lang/rust/pull/37094). – ljedrz

+0

Stabilna wersja której jest ... 9-ish tygodni od Ciebie? Tak jak powiedziałem, nie * właśnie. * –

+1

'let v = (1u64 .. 11) .collect :: >();' booo. 'let v: Vec = (1..11) .collect();' yaaay – Shepmaster

5

Wystarczy użyć .concat() na plasterek plasterki:

fn main() { 
    let v = (0u64 .. 10).collect::<Vec<_>>(); 
    let l = v.len(); 
    let first_and_last = [&v[..3], &v[l - 3..]].concat(); 
    println!("{:?}", first_and_last); 
    // The output is `[0, 1, 2, 7, 8, 9]` 
} 

ta tworzy nowy wektor, i współpracuje z dowolną liczbą plasterki.

(Playground link)

+0

Uwielbiam uczyć się nowych interfejsów API! – Shepmaster