Start learning free

LESSON 28 OF 414 · CALCULATIONS WITH NUMBERS

Increment and Decrement in Rust: No ++ or --, Use += 1

Lesson Read the full explanation

In programming, increasing the value of a variable by 1 is so common, there is an operator designed to do that.

In Rust there is no ++ operator, so we add 1 with += 1 (the increment):

let mut number: i32 = 10;
number += 1; // short for number = number + 1

println!("{}", number); // Output: 11

There is also one such operator for decreasing the value of a variable by 1.

Rust has no -- operator either, so we subtract 1 with -= 1 (the decrement):

let mut number: i32 = 10;
number -= 1; // short for number = number - 1

println!("{}", number); // Output: 9

Postfix:

Some languages have a postfix form, number++, which increments and returns the value before incrementing. Rust has no such operator, but we can get the same effect by reading the value first and then incrementing:

let mut number: i32 = 10;

let old_number = number;
number += 1;

println!("{}", old_number); // Output: 10
println!("{}", number); // Output: 11

This code first assigns the value of number (which is 10) to old_number and then increments number (making it 11). It's equivalent to this:

let old_number = number;
number += 1;

Prefix:

Other languages also have a prefix form, ++number, which increments and returns the value after incrementing. In Rust we get that by incrementing first and then reading the value:

let mut number: i32 = 10;

number += 1;
let new_number = number;

println!("{}", new_number); // Output: 11
println!("{}", number); // Output: 11

This code first increments number (making it 11) and then assigns the new value of number to new_number (making it 11). It's equivalent to this:

number += 1;
let new_number = number;

Here's an example with the decrement operator:

let mut number: i32 = 10;

number -= 1;
let new_number = number;

println!("{}", new_number); // Output: 9
println!("{}", number); // Output: 9

Assignment
Follow the Coding Tutorial and let's practice with these operators!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 5
    Ctrl + Enter to check

    RUST · CALCULATIONS WITH NUMBERS

    Increment And Decrement Operators in Rust, explained

    Adding or subtracting one

    Adding 1 to a variable, or subtracting 1 from it, is one of the most frequent changes a program makes: counting items, stepping through positions, counting down. Many languages have special operators for it, written ++ and --. Rust has neither. You use the augmented assignments += 1 and -= 1 instead.

    let mut number: i32 = 10;
    number += 1; // same as number = number + 1
    println!("{}", number); // 11
    
    number -= 1; // same as number = number - 1
    println!("{}", number); // 10
    

    Two things to notice. First, the variable must be declared with let mut, because Rust variables are immutable by default and these statements change the variable. Second, the compiler recognizes the habit from other languages and tells you what to write. Compiling x++; produces the error "Rust has no postfix increment operator" with the suggestion to use += 1.

    Post-increment and pre-increment

    In languages that have ++, the operator exists in two forms that behave differently when their value is used:

    • Post-increment (x++) gives the value from before the change, then increments.
    • Pre-increment (++x) increments first, then gives the value from after the change.

    In Rust, number += 1 is a statement, not a value you can use. As an expression it evaluates to the unit value (), so writing let y = (number += 1); stores () in y, which is rarely what anyone wants. To get the old or the new value, you spell out the order yourself with two statements.

    Post-increment: read first, then change

    let mut number: i32 = 10;
    
    let old_number = number;
    number += 1;
    
    println!("{}", old_number); // 10
    println!("{}", number);     // 11
    

    Because i32 is a plain number type, old_number receives a copy of the value. The later change to number does not affect it.

    Pre-increment: change first, then read

    let mut number: i32 = 10;
    
    number += 1;
    let new_number = number;
    
    println!("{}", new_number); // 11
    println!("{}", number);     // 11
    

    Decrementing works the same way with -= 1. Starting from 10, number -= 1; followed by let new_number = number; leaves both variables at 9.

    A block can also package "change, then read" into one expression. In let y = { x += 1; x }; the block runs the increment and then produces the final x as its value. With x starting at 5, both x and y become 6.

    A trap: --x compiles

    The expression --x is accepted by Rust, but it is not a decrement. It is a double negation: -(-x), which is just x again, and nothing changes. The compiler warns that the prefix -- could be misinterpreted as a decrement operator. ++x is not valid at all and gives the error "Rust has no prefix increment operator".

    The exercise, step by step

    The exercise tracks one variable through increments, decrements and the two reading patterns. The values below show what each step produces.

    1. Create the variable. let mut number = 18; uses mut because every later step changes it.
    2. Increment. number += 1; makes it 19.
    3. Simulate post-increment. Save the current value in post with let post = number;, then increment with number += 1;. Now post is 19 and number is 20.
    4. Simulate pre-increment. Increment first with number += 1;, which makes it 21, then capture it with let pre = number;. Now pre is 21.
    5. Decrement. number -= 1; brings number to 20.
    let mut number = 18;
    number += 1;
    let post = number;
    number += 1;
    number += 1;
    let pre = number;
    number -= 1;
    

    Two number += 1; lines sit side by side between post and pre. The first is the change that the post-increment pattern makes after saving. The second is the change that the pre-increment pattern makes before saving. Printing the three variables at the end gives 19 21 20. The type of number is inferred as i32, since nothing says otherwise.

    Common mistakes

    • Writing number++ or ++number. Both are compile errors. Write number += 1.
    • Expecting --number to decrement. It compiles but does nothing, apart from the compiler's warning.
    • Forgetting mut. Without it the compiler reports "cannot assign twice to immutable variable".
    • Saving the value in the wrong order. If let post = number; comes after the increment, it holds the new value, which is the pre-increment pattern.
    • Ignoring the type's range. In an optimized build, which is how these lessons are compiled, incrementing an i32 past its maximum wraps around silently. In a debug build, the same overflow panics.

    Key takeaways

    • Rust has no ++ or --. Use += 1 and -= 1 on a let mut variable.
    • The assignment itself produces no useful value, so "value before" and "value after" are written as two statements in the order you need.
    • Saving the value before the change imitates post-increment, and saving it after imitates pre-increment.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free