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
- Remove the
elsebranch. A number that isn't positive should not end the search. - Keep
return trueinside theif. A positive number settles the answer at once. - Add
return falseafter 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. - Leave
mainFunctionunchanged. 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 thatrangeproduces. Naming an unused index is a compile error in Go. iftakes a bool directly.if checkForPositive(...)needs no comparison withtrue.- Zero is not positive. The test is
num > 0, so a slice containing only zeros and negatives returnsfalse.
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 falseat the end. Keeping theelse { return false }makes the code compile, but the logic bug remains:[]int{-1, 2, 3}still givesfalse. - Putting
return falseinside 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
nilslice runs the loop zero times and returnsfalse, 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.