I'm a very beginner in Rust and I'm struggling to implement an algorithm.
Here is the "code" (which doesn't compile) I would like to make work in Rust:
fn main() {
println!(cumulated_evaluation([], 10));
}
fn cumulated_evaluation(arr: [String], depth: u32) -> i64 {
if 0 == depth {
return 0;
} else {
return cumulated_evaluation(
<arr with "some string" appended to it>,
depth - 1
) + evaluation_from_external_crate(&arr);
}
}
arr
can be of type Vec<String>
in cumulated_evaluation
but evaluation_from_external_crate
needs a &[String]
as input.
My problems:
Vec<String>
for arr
's type, how to use evaluation_from_external_crate
?A simple for loop can do this easily. You can use Vec<String>
, which can produce a &[String]
by calling as_slice
or by dereferencing &*
.
fn cumulated_evaluation(mut arr: Vec<String>, depth: u32) -> i64 {
let mut sum = 0;
for _ in 0..depth {
sum += evaluation_from_external_crate(arr.as_slice());
arr.push("some string".into());
}
sum
}
Now that it's not recursive, perhaps you would rather create arr
inside the function.
fn cumulated_evaluation(depth: u32) -> i64 {
let mut arr = Vec::with_capacity(depth as usize);
let mut sum = 0;
for _ in 0..depth {
sum += evaluation_from_external_crate(arr.as_slice());
arr.push("some string".into());
}
sum
}
Or you can create the whole Vec
up front and only pass parts of it to evaluation_from_external_crate
.
fn cumulated_evaluation(depth: u32) -> i64 {
let arr: Vec<String> = (0..depth - 1).map(|_| "some string".into()).collect();
let mut sum = 0;
for d in 0..(depth as usize) {
sum += evaluation_from_external_crate(&arr[0..d]);
}
sum
}
Or you could do the same thing but in a functional style.
fn cumulated_evaluation(depth: u32) -> i64 {
let arr: Vec<String> = (0..depth - 1).map(|_| "some string".into()).collect();
(0..(depth as usize))
.map(|d| &arr[0..d])
.map(evaluation_from_external_crate)
.sum()
}
You can't pass a plain slice (this is not an array) like arr: [String]
as a parameter because it is not sized. Such types can only be made values behind pointers, which is more-or-less what Vec
is doing. Rust arrays are denoted like arr: [String; 10]
and have a compile-time constant size that cannot change, although you can slice them just like Vec
and slices.