Reputation: 20124
I'm having some trouble passing a Vec<u64>
into a function without moving it. I have a function find_factors(mut n: u64, mut fctrs: Vec<u64>)
and I am currently calling from main like so:
fn main() {
let mut primeFactors: Vec<u64> = Vec::new();
find_factors(1134 as u64, primeFactors);
}
I'm forced right now to loop through and print out my vector in the find_factors
function because I'm not sure how to pass the Vec<u64>
by reference instead of moving it. How could I accomplish this? Example of what I want to do:
fn main() {
let mut primeFactors: Vec<u64> = Vec::new();
find_factors(1134 as u64, primeFactors);
//for ....
//print vector in main!
}
Upvotes: 33
Views: 53519
Reputation: 644
Consider passing ownership of the empty mutable vector into the function and returning the modified vector into the same variable. That way you stretch its lifetime and it can be safely used in the println!
macro.
The function find_factors
is a mocked version for this example. Please use your factorization algorithm there.
fn main() {
let mut prime_factors : Vec<u64> = Vec::new();
prime_factors = find_factors(164, prime_factors);
println!("Prime factors of 164 are {:?}", prime_factors);
}
fn find_factors(n: u64, mut prime_factors: Vec<u64>) -> Vec<u64> {
if n == 164 {
prime_factors.push(2);
prime_factors.push(2);
prime_factors.push(41);
}
prime_factors
}
This outputs:
Prime factors of 164 are [2, 2, 41]
Arguably you don't need to pass the empty and un-allocated vector into the function. Just return it from the function.
fn main () {
let prime_factors = find_factors(164);
println!("Prime factors of 164 are {:?}", prime_factors);
}
fn find_factors(n: u64) -> Vec<u64> {
let mut prime_factors: Vec<u64> = Vec::new();
if n == 164 {
prime_factors.push(2);
prime_factors.push(2);
prime_factors.push(41);
}
prime_factors
}
This produces the same result and it is a bit cleaner in my opinion.
Upvotes: 0
Reputation: 1
might be wrong but normally i just slap a .clone() at the end when im passing something into a function
Upvotes: -2
Reputation: 128111
If you don't need to add or remove elements from the vector, use slice (&[T]
) or mutable slice (&mut [T]
):
fn find_factors(n: u64, prime_factors: &mut [u64]) { ... }
let mut prime_factors: Vec<u64> = Vec::new();
find_factors(1134 as u64, prime_factors.as_mut_slice());
Immutable slices allow you to read elements or create subslices; mutable slices additionally allow to modify elements. But slices cannot grow - they are just a view into some vector.
It looks like you need to append new elements to the vector. You won't be able to do it using slice, as I said; you need to pass the vector itself using mutable reference:
fn find_factors(n: u64, prime_factors: &mut Vec<u64>) {
// here you can call e.g. prime_factors.push(...)
}
let mut prime_factors: Vec<u64> = Vec::new();
find_factors(1134 as u64, &mut prime_factors);
Upvotes: 52
Reputation: 15374
Use primeFactors.as_slice()
(or primeFactors.as_mut_slice()
if you want to modify the contents of the vector in place) to pass a vector as a borrowed pointer.
Change your function to accept a borrowed slice of type &[T]
.
Upvotes: 2