What the code is supposed to do
The function print_positive_and_negative goes through a vector of integers. For each number it should print the word negative if the number is less than zero, and the number itself otherwise. For [2, -12, 0, 4, -5, 3] the expected output is 2, negative, 0, 4, negative, 3, one item per line.
The starting code compiles but prints something else:
fn print_positive_and_negative(nums: Vec<i32>) {
for number in nums {
if number > 0 {
println!("positive");
}
println!("{}", number);
}
}
// Do not change this code:
fn main_function() {
print_positive_and_negative(vec![2, -12, 0, 4, -5, 3]);
}
It prints positive, 2, -12, 0, positive, 4, -5, positive, 3. There is an extra line before every positive number, and the negative numbers are printed as they are.
What goes wrong
Bug 1: the wrong condition and the wrong word
The if catches numbers greater than zero and prints positive. But the special message belongs to the numbers below zero, and it should say negative. The test is on the wrong side of zero, and the word is wrong.
Bug 2: the number is always printed
The last println! is outside the if, so it runs for every number. A number that got a message also gets printed afterwards, which is why 2 produces two lines. The task wants exactly one line per number: the word or the number, never both.
A choice between two outputs, where exactly one must happen, is what else is for.
Fixing it step by step
- Flip the condition to
number < 0, so the branch catches negative numbers only. - Change the message to
"negative". - Move the number print into an
else. It now runs only when the number is not negative, that is, for zero and positive numbers.
The fixed code in Rust
fn print_positive_and_negative(nums: Vec<i32>) {
for number in nums {
if number < 0 {
println!("negative");
} else {
println!("{}", number);
}
}
}
fn main_function() {
print_positive_and_negative(vec![2, -12, 0, 4, -5, 3]);
}
Trace the example: 2 is not negative, so 2 is printed. -12 is negative, so the word is printed. 0 is not below zero, so 0 is printed. 4 is printed. -5 gives the word. 3 is printed. That is the expected output, with six lines for six numbers.
Rust details
if/elsechooses exactly one branch. Whatever the condition says, only one of the two blocks runs for each number.- Zero goes to the
elsebranch. The condition is strictly less than zero, so 0 is printed as a number, as the expected output shows. - The condition has no parentheses. Rust requires a
boolthere and no brackets. A number alone, such asif number, is a compile error, since integers aren't converted to booleans. - Printing a value.
println!("{}", number)puts the number where the placeholder is. A quoted word like"negative"is printed as written. - The vector is moved into the loop.
for number in numsconsumes the vector, and eachnumberis a plaini32, sonumber < 0needs no dereference.
Common mistakes
- Using
<=. That would print the word for 0 too, but the task prints zero as a number. - Adding a second
ifinstead of anelse. Two separate tests could both fire or both miss. Usingelseguarantees exactly one line per number. - Fixing the word but not the structure. If the number print stays outside the
if, each negative number appears as the word and then as the number.
Testing
[2, -12, 0, 4, -5, 3]prints 2, negative, 0, 4, negative, 3.[-1]prints negative.[0]prints 0.[]prints nothing.
