2013-05-25 19 views
13

Chcę utworzyć wektor, ale znam tylko rozmiar, który chcę, aby wektor był w czasie wykonywania. Jest to, jak robię to teraz (czyli tworzenie pustego, zmienny wektor, wektorów i dodanie do niego):Tworzenie wektora o stałej długości

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; 
} 

ten sposób chcę to zrobić (tj, tworząc wektor i oddanie wszystko to, zamiast dodawania razem wiele wektorów):

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; 
} 

Niestety, robiąc powyższe daje mi coś takiego:

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

mam wrażenie, że wektory muszą mieć ich wielkość znany podczas kompilacji t ime (a więc musisz ustawić ich rozmiar na stałą wartość). Pochodzę z tła Java, jestem zdezorientowany! Czy istnieje sposób na stworzenie wektora, którego rozmiar znasz tylko w czasie wykonywania?

Używam Rust 0.6.

+1

To było dobre zadanie, ale teraz jest już dość przestarzałe, biorąc pod uwagę wszystkie zmiany z rdzy 0.6 do 1.0 ... – poolie

Odpowiedz

9

Nie można utworzyć wektora o stałej długości z długością określoną w czasie wykonywania, dozwolone są tylko wektory o stałej długości podczas kompilacji, więc (warianty) pierwszej metody z ~[int] jest jedynym obsługiwanym sposobem. Możesz użyć vec::from_elem(number_of_pairs, 0), aby utworzyć wektor o właściwym rozmiarze i użyć drugiej części.


Istnieje wiele funkcji pomocniczych do czego staramy się robić (używając while bezpośrednio Rust powinny być bardzo rzadkie):

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 
} 

Albo nawet

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

Docs: chunks, filter, map, collect. (The filter to tylko dlatego, że ostatni element może mieć długość chunks 1.)

(również pamiętać, że dodanie dwóch wektorów przydziela jeden zupełnie nowy, a push nie koniecznie to zrobić i jest znacznie szybsze (i .collect jest podobny).)

+0

Dzięki za sugestie składni: wciąż walczę z dokumentami! – Daniel

+0

Wszyscy są :) to jeden z największych problemów z Rustem w tej chwili. (Inne miejsca, w których można zadawać pytania dotyczące Rust to kanał [IRC] (http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) i [lista adresowa] (https: // mail. mozilla.org/listinfo/rust-dev), prawie zawsze mają kogoś chętnego do pomocy.) – huon

+0

Fajnie, dzięki! Wypróbuję je. – Daniel

2

W późniejszych wersjach Rusta (używam 0.9), jest teraz funkcja with_capacity() w std::vec, która obsługuje ten scenariusz.

Przykładowy kod:

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' jest nieco inny: po prostu alokuje tyle pamięci, nie wypełnia tego wektora elementami. – huon

13

W wersji 1.0.0 Rust zrobili ten std::vec:Vec strukturę publiczną stabilny, dzięki czemu można instancji growable wektor z let mut my_vec = Vec::new(); Można również użyć vec! makro tak: let mut another_vec = vec![1isize, 2isize, 3isize]; Ważne jest, aby pamiętać, że w obu przypadkach przypisywana zmienna musi być zmienna.

Z tych wektorów można nazwać my_vec.push(num); do poszczególnych elementów (stabilna), lub another_vec.push_all(["list", "of", "objects"]); (niestabilny), aby dodać elementy do końca wektora.

Więc dla danego problemu, można zrobić coś takiego

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 
} 

Można to zobaczyć w akcji here gdzie masz (co Przypuszczałem) był zagnieżdżona wektor par całkowitych.

+1

Kompilator wyrzuca teraz ostrzeżenia "i" i "jest", ale szybko naprawiłem przykład na "isize" [tutaj] (http://bit.ly/1bnX0aC) –

Powiązane problemy