Start learning free

LESSON 148 OF 414 · LOOPS & GLOBAL VARIABLES

Buggy Code: Array Sum in Rust

Practice Read the full explanation

Inside the code editor we've tried to write a function that takes a vector nums as argument and prints to the console the sum of all numbers in that vector.

So when we called printSum(vec![1, 2, 3]), we expected our code to print:

6

because 1 + 2 + 3 = 6. But it seems like we made some mistakes because when we run our code, it prints:

1
2
3

Assignment:

Your task is to fix our function such that it correctly computes and prints the desired sum.

STEP 1 OF 1
    Ctrl + Enter to check

    RUST · LOOPS & GLOBAL VARIABLES

    Buggy Code Array Sum in Rust, explained

    Problem overview

    The function printSum receives a vector of integers, nums, and should print the total of all its elements once. Called with vec![1, 2, 3], it should print 6, because 1 + 2 + 3 = 6. The code as given prints three lines instead: 1, 2 and 3.

    The task is to fix the function without changing the code that calls it. There are two mistakes, and both are about where a line sits relative to the loop.

    Finding the bugs

    This is the buggy version:

    fn printSum(nums: Vec<i32>) {
        for num in &nums {
            let mut sum = 0;
            sum += num;
            println!("{}", sum);
        }
    }
    

    Tracing the loop by hand for 1, 2, 3 shows what happens on each pass:

    1. With num = 1, a new sum is created at 0, becomes 1 and is printed.
    2. With num = 2, a new sum is created at 0 again, becomes 2 and is printed.
    3. With num = 3, the same happens and 3 is printed.

    Bug 1: the accumulator is declared inside the loop

    A variable declared in a block exists only inside it. The line let mut sum = 0; sits in the loop body, so every pass creates a new sum and the old one is gone. Nothing carries over from one number to the next, and the total can never build up. The declaration must go above the loop.

    Bug 2: the print is inside the loop

    The println! is also in the loop body, so it runs once per element. The total is only complete after the last element has been added, so the print belongs after the loop.

    Fixing only the first bug still produces output, but the wrong one. With the declaration moved and the print left inside, the function prints the running totals 1, 3 and 6 on three lines instead of a single 6.

    The solution in Rust

    fn printSum(nums: Vec<i32>) {
        let mut sum = 0;
        for num in &nums {
            sum += num;
        }
        println!("{}", sum);
    }
    fn mainFunction() {
        printSum(vec![1, 2, 3]);
    }
    

    The Rust details worth noting:

    • Borrowing in the loop. for num in &nums iterates over references, so num has the type &i32. Rust allows sum += num with a reference on the right-hand side of an i32 addition, so no dereference is needed. Writing sum += *num gives the same result.
    • Why &nums. Looping over nums itself would move the vector into the loop. Borrowing it leaves nums intact after the loop.
    • Type inference. The compiler gives sum the type i32, because it is added to i32 values.
    • Names. The lesson's printSum and mainFunction are in camel case, where Rust style prefers snake case. This compiles with a style warning, and the lesson's tests look for these names, so keep them.

    Edge cases and common mistakes

    • An empty vector. The loop does not run, and the function prints 0.
    • Negative numbers. vec![-5, 5, 10] prints 10. The same code works unchanged.
    • Moving only one of the two lines. Both the declaration and the print have to move. Each one alone leaves a wrong output.
    • Declaring sum without mut. It is a compile error, because sum += num assigns to it.
    • Overflow. The total is an i32. If the elements add up to more than 2,147,483,647, the optimized build wraps around silently, and a debug build panics.

    Testing

    • vec![1, 2, 3] prints 6.
    • vec![] prints 0.
    • vec![-5, 5, 10] prints 10.
    • vec![7] prints 7.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free