Start learning free

LESSON 131 OF 338 · LOOPS & CONDITIONALS

Positive Number in Array in Go: Fixing the Buggy Code

Practice Read the full explanation

Inside the code editor we've tried to write a function that takes an array nums as argument and returns true if there exists at least one positive (greater than zero) number in the array; returns false otherwise.

So when we called the function for []int{-1, 2, 3}, we expected our code to print:

Array has positive numbers

but it seems like we made some mistakes because when we run our code, it prints:

Array doesn't have positive numbers

Assignment:

Your task is to fix our function.

STEP 1 OF 1
    Ctrl + Enter to check

    GO · LOOPS & CONDITIONALS

    Buggy Code Check For Positive Numbers in Go, explained

    What the code is supposed to do

    The function checkForPositive takes a slice of integers and returns true if at least one number is greater than zero, and false otherwise. The program calls it with []int{-1, 2, 3} and prints Array has positive numbers when the result is true.

    The starting code does not compile:

    func checkForPositive(nums []int) bool {
        for _, num := range nums {
            if num > 0 {
                return true
            } else {
                return false
            }
        }
    }
    

    The Go compiler stops with missing return. Even once that is fixed, the logic has a second problem.

    What goes wrong

    The logic: the first element decides everything

    Both branches of the if return. On the first pass through the loop, num is -1. It is not positive, so the else branch returns false and the function ends. The elements 2 and 3 are never looked at. A function that should answer "is there any positive number?" is answering "is the first number positive?".

    One number that fails the test says nothing about the others. The answer false is only justified once every element has been checked and none was positive. The answer true is justified the moment one positive number appears.

    The compile error: a path with no return

    Go checks that a function with a result type ends in a return statement, or in something that provably never finishes. Here, the loop might not run at all, as with an empty slice, and then execution falls out of the loop and reaches the closing brace with no value to hand back. Go does not reason that the loop body always returns on its first pass, so it reports missing return.

    Fixing it step by step

    1. Remove the else branch. A number that isn't positive should not end the search.
    2. Keep return true inside the if. A positive number settles the answer at once.
    3. Add return false after the loop. It is reached only when every element was checked and none was positive. It also gives every path a return, which fixes the compile error.
    4. Leave mainFunction unchanged. It already prints the right message based on the result.

    The fixed code in Go

    func checkForPositive(nums []int) bool {
        for _, num := range nums {
            if num > 0 {
                return true
            }
        }
        return false
    }
    
    func mainFunction() {
        if checkForPositive([]int{-1, 2, 3}) {
            fmt.Println("Array has positive numbers")
        } else {
            fmt.Println("Array doesn't have positive numbers")
        }
    }
    

    For []int{-1, 2, 3} the loop skips -1, reaches 2, returns true, and the program prints Array has positive numbers.

    Go details worth knowing:

    • The blank identifier. _ discards the index that range produces. Naming an unused index is a compile error in Go.
    • if takes a bool directly. if checkForPositive(...) needs no comparison with true.
    • Zero is not positive. The test is num > 0, so a slice containing only zeros and negatives returns false.

    Two ways to think about it

    The fixed function follows a pattern you will meet again: "does any element satisfy a condition?". Return true from inside the loop as soon as one does, and return false after the loop. The opposite question, "do all elements satisfy a condition?", flips the roles: return false inside the loop on the first element that fails, and true after the loop. In both patterns, the answer that needs every element to be checked belongs after the loop.

    The starting code mixed the two patterns. It gave an answer for each possible outcome of one element, but a single element can only prove the "any" question true, never false.

    Tracing the fixed loop

    Follow []int{-1, 2, 3} pass by pass. On the first pass num is -1, the test num > 0 is false, and nothing happens, so the loop moves on. On the second pass num is 2, the test is true, and return true ends the function. The value 3 is never examined, because the answer is already known. Now follow []int{-3, 0}: both passes fail the test, the loop ends, and execution reaches return false. Each answer comes from the one place in the code that can prove it.

    Reading compiler errors

    The message missing return points at the closing brace of the function. It means that the compiler found a way to reach the end without a value, not that a particular line is wrong. When you see it, ask which path leaves the function without returning, and here that path is the loop finishing. Fixing the compile error alone is not enough, since a program that compiles can still answer the wrong question. Fix the logic first, and the missing return usually falls into place.

    Common mistakes

    • Adding only return false at the end. Keeping the else { return false } makes the code compile, but the logic bug remains: []int{-1, 2, 3} still gives false.
    • Putting return false inside the loop. It would run on the first non-positive number and stop the search early.
    • Checking num >= 0. That treats zero as positive.
    • Forgetting the empty slice. With the fix, an empty or nil slice runs the loop zero times and returns false, which is correct, since there is no positive number.

    Checking your fix

    Run the code in the editor above. The program should print Array has positive numbers. Other inputs worth trying: []int{-3, -1} gives false, []int{0, 0} gives false, and []int{5} gives true.

    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free