The task
The program starts with two integer variables, width and height, holding the sides of a rectangle. It must print the rectangle's area. The area of a rectangle is its width multiplied by its height, so the program has one job: multiply the two variables and show the result.
With width equal to 23 and height equal to 17, the area is 23 times 17, which is 391.
Step by step
- Write the multiplication as
width * height. The*operator multiplies two numbers, and it works on variables just as it does on literals. - Hand the expression to
println!. The macro takes a format string first. Each{}placeholder in that string is replaced by the next value after the comma, so"{}"with one value prints just that value. - Skip the extra variable. You could store the area in a new variable and print that, but the expression can go straight into the print call, and for a one-time result that is shorter.
The solution in Rust
let width: i32 = 23;
let height: i32 = 17;
println!("{}", width * height);
It prints 391 followed by a line break. The multiplication happens first, and println! receives the finished number.
Storing the result first
If you want to reuse the area later, a variable makes sense. This version prints the same thing:
let width: i32 = 23;
let height: i32 = 17;
let area = width * height;
println!("{}", area);
Rust infers that area is an i32 because both operands are. The annotations : i32 on width and height could be left out, since an integer literal defaults to i32.
What println! does with the value
The macro formats the number as text using its default display form, then adds a line break. For an integer that is just the digits. If you want the output to stay on the same line, print! works the same way without the line break. The value you pass is not changed: after the print, width and height still hold 23 and 17, and the area is computed again each time the expression is evaluated.
Variations on the same idea
The same pattern covers related calculations. The perimeter is 2 * (width + height), which is 80 for these sides. The parentheses make the addition happen before the multiplication by 2. And if the sides can have decimals, declare them as f64 and write the area the same way:
let width: f64 = 2.5;
let height: f64 = 3.5;
println!("{}", width * height); // 8.75
Only the types changed. The expression width * height stays exactly the same, and that is the point of working with variables: the calculation describes a relationship, and the data can change without touching it.
Things that can go wrong
- Putting the expression inside the quotes.
println!("width * height")prints those characters literally. The expression belongs after the comma, outside the string. - Forgetting the placeholder.
println!("{}")with no value after it, or a value with no{}to receive it, doesn't compile. The number of placeholders must match the number of values. - Using
+by mistake.width + heightgives 40, which is half the perimeter, not the area. - Mixing types. If
widthwere anf64andheightani32, the multiplication would not compile, because Rust doesn't multiply a float by an integer. Both sides need the same type. - Overflow. An
i32tops out at 2147483647, so two sides of 50000 would exceed it. An optimized build (rustc -O) wraps silently and gives-1794967296, while a debug build panics. For sides that large, declare the variables asi64, which gives 2500000000.
Key takeaways
- Multiplication in Rust is
*, and it takes variables as readily as numbers. - An expression can be passed directly to
println!, which prints its value where the{}is. - Both operands of an arithmetic operator must have the same numeric type.
