Chuyển đổi Vec <Vec <u8>> thành & [& [u8]] [trùng lặp]
Tôi có một hàm nhận một số chuỗi byte: &[&[u8]]nhưng muốn gọi nó với một đối số kiểu Vec<Vec<u8>>. Gọi hàm như thế này:
let foo: Vec<Vec<u8>> = Vec::new();
bar(&foo[..]);
chuyển đổi foothành một lát nhưng không chuyển đổi các giá trị mà nó chứa. Có cách nào để thực hiện chuyển đổi này dễ dàng và hiệu quả không? Hoặc tôi có thể thay đổi kiểu của đối số hàm để tránh những trường hợp như thế này không?
Trả lời
Một cách để xử lý trường hợp này mà không cần phân bổ thêm Veclà sử dụng AsRef<[u8]>:
fn bar<S: AsRef<[u8]>>(args: &[S]) {
// ...
}
Bên trong hàm, bạn có thể sử dụng .as_ref()để chuyển đổi từng đối số thành a &[u8].
( sân chơi )
Từ góc độ trí nhớ, điều này không có nhiều ý nghĩa. Để tạo một lát cắt, trước tiên dữ liệu được cắt lát phải tồn tại trong bộ nhớ. Tuy nhiên, để thực hiện một phần &[u8], trước tiên bạn cần phải có một số cấu trúc dữ liệu Vec<&[u8]>để lấy phần này.
Nói cách khác để làm điều này, trước tiên bạn cần phân bổ không gian cho Vec<&[u8]>hoặc [&[u8]; N]và lấp đầy nó bằng các lát. Điều này phần nào đánh bại mục đích của việc sử dụng các lát vì các lát cắt có ý nghĩa với bộ nhớ tham chiếu hiện có tại chỗ. &[Vec<u8>]Thay vào đó, hãy cân nhắc sử dụng cho chức năng của bạn.
Nếu việc có các lát trong lớp thứ hai là quan trọng hoặc bạn không thể chỉnh sửa hàm, bạn có thể làm như sau để chuyển đổi Vec<Vec<u8>>thành &[&[u8]]:
let foo: Vec<Vec<u8>> = Vec::new();
// Allocate Vec of references to slices
let tmp: Vec<&[u8]> = foo.iter().map(|x| &x[..]).collect();
// Take slice of temporary Vec
bar(&tmp[..]);