Problem overview
The function computeSum should return the sum of the numbers from 0 up to n - 1. For computeSum(4) the expected result is 0 + 1 + 2 + 3 = 6, and the program should print 6. The code as given prints 16 instead.
The task is to find the mistake and fix it. Neither the loop nor the return statement is wrong in shape. The error is in one name.
Finding the bug
The buggy version of the function looks like this:
fn computeSum(n: i32) -> i32 {
let mut sum = 0;
for i in 0..n {
sum += n;
}
return sum;
}
The wrong output, 16, is a clue. It equals 4 + 4 + 4 + 4, which is n added four times. The loop runs four times, with i equal to 0, 1, 2 and 3, but the body never uses i. It adds the function argument n, which is 4 on every pass.
Following the loop by hand shows it:
- Before the loop,
sumis 0. - With
i = 0,sum += 4makes it 4. - With
i = 1, it becomes 8. - With
i = 2, it becomes 12. - With
i = 3, it becomes 16.
In general, this code adds n to the total n times, so it returns n * n whatever the loop variable does.
A second clue comes from the compiler. Because i is never used, rustc warns that the variable is unused and suggests the name _i. A warning like this does not stop the program from compiling, but it often points straight at a bug of this kind: the loop variable was declared and then ignored.
The fix
The running total must grow by the value that changes from pass to pass, which is i. Changing sum += n; to sum += i; adds 0, then 1, then 2, then 3:
i = 0leavessumat 0.i = 1makes it 1.i = 2makes it 3.i = 3makes it 6.
The loop range stays 0..n. Since a Rust range excludes its end, i stops at n - 1, which is exactly what the task describes.
The solution in Rust
fn computeSum(n: i32) -> i32 {
let mut sum = 0;
for i in 0..n {
sum += i;
}
return sum;
}
fn mainFunction() {
println!("{}", computeSum(4));
}
The Rust details worth noting:
- The range
0..n. It starts at 0 and stops beforen. With0..=nthe sum would includenas well, andcomputeSum(4)would be 10. - Compound assignment.
sum += i;meanssum = sum + i;. The variable needsmutbecause it changes. - The return type. The signature says
-> i32, and the function ends withreturn sum;. Writing justsumwithout a semicolon would do the same. - Names. Rust style prefers
compute_sumin snake case. The lesson usescomputeSum, which compiles with a style warning. Keep the lesson's names so that the lesson's tests find them.
Edge cases and common mistakes
n = 0orn = 1. For 0 the range is empty and the function returns 0. For 1 the only value is 0, so the result is 0 as well.- Negative
n. A range such as0..-3is empty, so the function returns 0. - Other inputs.
computeSum(5)returns 10, andcomputeSum(3)returns 3. - Changing the wrong thing. Switching the range to
1..ndoes not fix the bug, because the body still addsn. Switching to1..=nwithsum += iwould add the wrong numbers for this task. - Ignoring warnings. An unused variable is a hint. When the loop variable never appears in the loop body, the loop is probably repeating the same work.
