What the code is supposed to do
The function printSum takes an IntArray named nums and should print one number: the sum of all its elements. The function mainFunction calls it with intArrayOf(1, 2, 3), and since 1 + 2 + 3 = 6, the expected output is a single line:
6
The code you start with compiles and runs, but prints three lines instead:
1
2
3
Nothing is wrong with the syntax. The logic has two mistakes, and the lesson asks you to find and fix both without touching the code that calls printSum.
What goes wrong
Here is the buggy function:
fun printSum(nums: IntArray) {
for (num in nums) {
var sum = 0
sum += num
println(sum)
}
}
Trace it by hand for the array 1, 2, 3. Each pass of the loop runs every line of the body from the top.
- The variable is recreated on every pass.
var sum = 0sits inside the loop, so each pass creates a newsumthat starts at 0 and is thrown away at the closing brace. Addingnumto it gives justnum. The earlier numbers are never remembered, because the variable that held them no longer exists. - The print is inside the loop.
println(sum)runs once per element, so the function prints three times. The total is only complete after the last element has been added, so the print belongs after the loop.
The two mistakes hide each other. Fixing only the first gives a different wrong output: the running totals, printed on separate lines.
fun printSum(nums: IntArray) {
var sum = 0
for (num in nums) {
sum += num
println(sum)
}
}
For 1, 2, 3 this prints 1, 3 and 6. The last line is the right answer, but two extra lines come before it. Fixing only the second mistake, by moving the print out of the loop while leaving var sum = 0 inside it, doesn't compile, because sum only exists inside the loop body.
Fixing it step by step
- Move the declaration above the loop. Write
var sum = 0beforefor. It now exists once for the whole function call, starts at 0 and keeps its value from one pass to the next. - Keep the addition in the loop.
sum += numadds the current element to the running total on every pass. - Move the print below the loop. After the closing brace,
println(sum)runs once, when every element has been added. - Leave
mainFunctionalone. It already callsprintSumwith 1, 2 and 3.
The fixed code in Kotlin
fun printSum(nums: IntArray) {
var sum = 0
for (num in nums) {
sum += num
}
println(sum)
}
// Do not change this code:
fun mainFunction() {
printSum(intArrayOf(1, 2, 3))
}
The Kotlin details behind it:
- Scope follows the braces. A variable declared inside a block is visible only from its declaration to the end of that block. A
vardeclared in the loop body is new on every pass. One declared before the loop belongs to the function body and outlives all the passes. varis needed for a running total. Avalcan't be reassigned, sosum += numwould not compile with it.IntArrayandintArrayOf.IntArrayis a fixed-size array of primitive 32-bit integers, andintArrayOf(1, 2, 3)creates one. The loopfor (num in nums)visits the elements in order and needs no index.- The sum is an
Int. Becausesumstarts as the literal 0, Kotlin infers the typeInt, which is 32 bits. The total silently wraps around if it passes 2,147,483,647:intArrayOf(2147483647, 1)prints -2147483648. ALongaccumulator (var sum = 0L) would avoid that.
Common mistakes
- Printing the running total. Leaving
printlnin the loop prints 1, 3, 6 instead of 6. - Resetting the total. Any assignment of 0 to
suminside the loop erases the work done so far. - Starting from the wrong value. The total must start at 0, the neutral value for addition. Starting at 1 gives 7 for this input.
- Forgetting the empty array. With
intArrayOf()the loop never runs and the fixed function prints 0, which is the correct sum of no numbers. - Changing the caller. The lesson's tests expect
mainFunctionto stay as it is.
Checking your fix
Run the code in the editor above. A correct fix prints exactly one line, 6. If you see several lines, the print is still inside the loop. If the compiler reports an unresolved reference to sum, the declaration is still inside the loop while the print is outside it. For other inputs, intArrayOf(-4, 4, 10) should print 10.