2013-05-25 34 views
13

Tôi muốn tạo một véc-tơ, nhưng tôi chỉ biết kích thước tôi muốn vectơ ở thời gian chạy. Đây là cách tôi đang làm nó bây giờ (tức là tạo ra một sản phẩm nào, vector có thể thay đổi, và thêm vectơ với nó):Tạo một véc tơ có độ dài không đổi

fn add_pairs(pairs: ~[int]) -> ~[int] { 
    let mut result : ~[int] = ~[]; 
    let mut i = 0; 
    while i < pairs.len() { 
     result += ~[pairs[i] + pairs[i + 1]]; 
     i += 2; 
    } 
    return result; 
} 

đây là cách tôi muốn làm điều đó (ví dụ, tạo ra một vector và đưa tất cả mọi thứ trong nó, thay vì thêm nhiều vectơ với nhau):

fn add_pairs(pairs: ~[int]) -> ~[int] { 
    let number_of_pairs = pairs.len()/2; 
    let result : ~[int, ..number_of_pairs]; 
    let mut i = 0; 
    while i < pairs.len() { 
     result[i] = pairs[2 * i] + pairs[2 * i + 1]; 
     i += 1; 
    } 
    return result; 
} 

Thật không may, làm việc ở trên mang lại cho tôi một cái gì đó như:

error: expected constant expr for vector length: Non-constant path in constant expr 
let result: ~[int, ..number_of_pairs]; 
      ^~~~~~~~~~~~~~~~~~~~~~~~ 

tôi có ấn tượng rằng vectơ phải có kích thước của chúng được biết đến lúc biên dịch t ime (và vì vậy bạn cần đặt kích thước của chúng thành hằng số). Đến từ một nền Java, tôi bối rối! Có cách nào để tạo ra một vector có kích thước mà bạn chỉ biết khi chạy không?

Tôi đang sử dụng Rust 0.6.

+1

Đây là một questinon tốt nhưng bây giờ khá lạc hậu cho tất cả những thay đổi từ Rust 0.6 đến 1.0 ... – poolie

Trả lời

9

Không có cách nào để tạo vectơ có độ dài không đổi với độ dài được xác định khi chạy, chỉ cho phép vectơ độ dài không đổi thời gian biên dịch, do đó (các biến thể) phương pháp đầu tiên của bạn với ~[int] là cách duy nhất được hỗ trợ. Bạn có thể sử dụng vec::from_elem(number_of_pairs, 0) để tạo một vectơ có kích thước chính xác và sử dụng phần thứ hai.


Có rất nhiều chức năng helper cho những gì bạn đang cố gắng làm (sử dụng while trực tiếp Rust nên rất hiếm):

fn add_pairs(pairs: &[int]) -> ~[int] { 
    let mut result = ~[]; 
    for i in uint::range(0, pairs.len()/2) { 
     result.push(pairs[2*i] + pairs[2*i+1]) 
    } 
    result 
} 

Hoặc thậm chí

fn add_pairs(pairs: &[int]) -> ~[int] { 
    pairs.chunks(2).filter(|x| x.len() == 2).map(|x| x[0] + x[1]).collect() 
} 

Documents: chunks, filter, map, collect. (Các filter là chỉ vì yếu tố cuối cùng của chunks có thể có chiều dài 1.)

(Ngoài ra, lưu ý rằng việc thêm hai vectơ phân bổ một hoàn toàn mới, trong khi push không làm được điều này nhất thiết và là nhanh hơn nhiều (và .collect tương tự).)

+0

Cảm ơn các gợi ý cú pháp quá: Tôi vẫn đang đấu tranh với các tài liệu! – Daniel

+0

Mọi người đều là :) đó là một trong những vấn đề lớn nhất với Rust lúc này. (Những nơi khác để đặt câu hỏi về Rust là kênh [IRC] (http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) và [mailing list] (https: // mail). mozilla.org/listinfo/rust-dev), họ hầu như luôn sẵn sàng giúp đỡ ai đó.) – huon

+0

Thật tuyệt vời! Tôi sẽ thử chúng. – Daniel

2

Trong các phiên bản sau của Rust (tôi đang sử dụng 0.9), hiện tại có chức năng with_capacity() trong std::vec xử lý trường hợp này.

Ví dụ mã:

use std::vec; 

// ... 

let n = 44; // pretend determined at run time 
let mut v = vec::with_capacity::<f64>(n); 
v.push(6.26); 
println("{:?}", v);    // prints ~[6.26f64] 
println("{:?}", v.len());  // prints 1u 
println("{:?}", v.capacity()); // prints 44u 
+1

'with_capacity' hơi khác một chút: nó chỉ phân bổ nhiều lưu trữ sao lưu, nó không điền vào vectơ với các phần tử. – huon

13

Trong phiên bản 1.0.0 Rust họ đã thực hiện các cấu trúc công cộng std::vec:Vec ổn định để bạn có thể nhanh chóng một vector growable với let mut my_vec = Vec::new(); Bạn cũng có thể sử dụng vec! vĩ mô như vậy: let mut another_vec = vec![1isize, 2isize, 3isize]; Điều quan trọng cần lưu ý là trong cả hai trường hợp, biến bạn đang gán phải có thể thay đổi.

Với các vectơ này, bạn có thể gọi my_vec.push(num); cho các mục riêng lẻ (ổn định) hoặc another_vec.push_all(["list", "of", "objects"]); (không ổn định) để thêm các mục vào cuối vectơ.

Vì vậy, đối với vấn đề cụ thể của bạn, bạn có thể làm một cái gì đó như thế này

fn add_pairs(pairs: Vec<(Vec<isize>)>) -> Vec<isize> { 
    let mut result = Vec::new(); 
    for pair in pairs.iter() { 
     result.push(pair[0]); 
     result.push(pair[1]); 
    } 
    return result 
} 

Bạn có thể thấy điều này trong hành động here nơi bạn đã (những gì tôi giả định) là một véc tơ lồng nhau của các cặp số nguyên.

+1

Trình biên dịch ném cảnh báo về 'i' và 'là' ngay bây giờ, nhưng tôi đã nhanh chóng sửa ví dụ thành 'isize' [ở đây] (http://bit.ly/1bnX0aC) –

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