2016-10-01 15 views
8

Tôi muốn tạo một HashSet<u8> từ một Vec<u8>. Tôi muốn làm điều nàyXây dựng HashSet từ một vector trong Rust

  1. trong một dòng mã,
  2. sao chép các dữ liệu chỉ một lần,
  3. chỉ sử dụng 2n nhớ,

nhưng điều duy nhất tôi có thể tới biên dịch là mảnh này .. rác, mà tôi nghĩ rằng sao chép dữ liệu hai lần và sử dụng bộ nhớ 3n.

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

Tôi đã hy vọng để viết một cái gì đó đơn giản, như thế này:

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

nhưng điều đó sẽ không biên dịch:

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, _>` 

.. và tôi không thực sự hiểu được những lỗi tin nhắn, có lẽ vì tôi cần RTFM.

+1

Mã và thông báo lỗi không khớp. Bạn phải có nghĩa là 'iter() ' – bluss

+0

FYI: trong mã đầu tiên của bạn, bạn không cần sao chép vectơ, bạn chỉ cần khai báo nó là có thể thay đổi được. Hoặc bằng 'let mut victim = vec;' hoặc trong danh sách đối số bởi: 'fn vec_to_set (mut vec: Vec )'. –

+4

Bạn không sử dụng ký hiệu * O * một cách chính xác. _O (n) = O (2n) = O (3n) = O (c * n) _. Vấn đề là hằng số không quan trọng. Tôi nghĩ rằng nó là rõ ràng những gì bạn có nghĩa là nhưng bạn có lẽ nên nói chỉ là "_2n_ bộ nhớ" hoặc một cái gì đó để thay thế. – Lii

Trả lời

11

Một thay thế:

Bởi vì hoạt động không cần phải tiêu thụ vector¹, tôi nghĩ rằng nó không nên tiêu thụ nó. Đó chỉ dẫn đến sao chép thêm ở một nơi khác trong chương trình:

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

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

Gọi nó như hashset(&v) nơi v là một Vec<u8> hoặc khác điều mà cưỡng ép để một lát.

Có nhiều cách để viết điều này, là chung chung và tất cả điều đó, nhưng câu trả lời này chỉ đề cập đến điều tôi muốn tập trung vào.

¹Điều này dựa trên yếu tố loại u8Copy, tức là nó không có ngữ nghĩa quyền sở hữu.

11

Sau đây sẽ hoạt động tốt; nó đáp ứng yêu cầu của bạn:

use std::iter::FromIterator; 

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

from_iter() công trình trên các loại thực hiện IntoIterator, do đó, một lập luận Vec là đủ.

nhận xét bổ sung:

  • bạn không cần phải rõ ràng return kết quả chức năng; bạn chỉ cần bỏ qua các dấu chấm phẩy trong biểu thức cuối cùng trong cơ thể của nó

  • Tôi không chắc chắn phiên bản nào của Rust bạn đang sử dụng, nhưng trên ổn định hiện nay (1.12) to_iter() không tồn tại

Các vấn đề liên quan