2016-10-01 16 views
8

Chcę zbudować HashSet<u8> z Vec<u8>. Chciałbym zrobić toBuduj HashSet z wektora w Rust

  1. w jednej linii kodu,
  2. kopiując dane tylko raz,
  3. używając tylko 2n pamięć,

ale jedyną rzeczą, mogę dostać się do kompilacja to ten kawałek ... śmieci, który moim zdaniem dwukrotnie kopiuje dane i korzysta z pamięci 3n.

fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> { 
    let mut victim = vec.clone(); 
    let x: HashSet<u8> = victim.drain(..).collect(); 
    return x; 
} 

miałem nadzieję napisać coś prostego, na przykład:

fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> { 
    return HashSet::from_iter(vec.iter()); 
} 

jednak, że nie będzie skompilować:

error[E0308]: mismatched types 
--> <anon>:5:12 
    | 
5 |  return HashSet::from_iter(vec.iter()); 
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found &u8 
    | 
    = note: expected type `std::collections::HashSet<u8>` 
    = note: found type `std::collections::HashSet<&u8, _>` 

.. a ja naprawdę nie rozumiem błąd wiadomość, prawdopodobnie dlatego, że potrzebuję RTFM.

+1

Kod i komunikat o błędzie nie pasują do siebie. Musisz mieć na myśli 'iter()' – bluss

+0

FYI: w twoim pierwszym kodzie nie musisz klonować wektora, wystarczy zadeklarować go jako zmienny. Albo przez 'let mut ofiar = vec;' lub na liście argumentów przez: 'fn vec_to_set (mut vec: Vec )'. –

+4

Nie używasz notacji * O * poprawnie. _O (n) = O (2n) = O (3n) = O (c * n) _. Chodzi o to, że stałe nie mają znaczenia. Myślę, że jasne jest, co masz na myśli, ale powinieneś raczej powiedzieć "_2n_ memory" lub coś takiego. – Lii

Odpowiedz

11

Inną alternatywą:

Ponieważ operacja nie musi spożywać vector¹, myślę, że nie należy go spożywać. To prowadzi tylko do dodatkowego kopiowania gdzieś indziej w programie:

use std::collections::HashSet; 
use std::iter::FromIterator; 

fn hashset(data: &[u8]) -> HashSet<u8> { 
    HashSet::from_iter(data.iter().cloned()) 
} 

nazwać to jak hashset(&v) gdzie v jest Vec<u8> lub inną rzecz, która wymusza na plaster.

Jest oczywiście więcej sposobów na napisanie tego, bycie ogólnym i tym podobne, ale ta odpowiedź ma na celu jedynie przedstawienie tego, na czym chciałem się skupić.

¹ Podstawą tego jest to, że typ elementu u8 to Copy, tj. Nie ma semantyki własności.

11

Następujące powinny ładnie działać; spełnia wymagania:

use std::iter::FromIterator; 

fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> { 
    HashSet::from_iter(vec) 
} 

from_iter() działa na rodzaje wykonawczych IntoIterator, więc Vec argument jest wystarczający.

Uwagi dodatkowe:

  • nie trzeba jawnie return wyników funkcji; wystarczy pominąć średnik w ostatniej wypowiedzi w jego organizmie

  • Nie jestem pewien, która wersja Rust używasz, ale w obecnej stajni (1,12) to_iter() nie istnieje