We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Shape Your Data: Structs, Enums, Pattern Matching step 1 of 26
Structs: naming your data
Complete the construction of a Rect from its width and height. Return its
area and perimeter as text, each with two decimal places, separated by one
space. Do not add a newline.
pub fn describe_rect(w: f64, h: f64) -> String
Use the supplied Rect type and its methods. The area is w * h, and the
perimeter is 2.0 * (w + h). Inputs are finite, nonnegative dimensions small
enough that both calculations remain finite. Zero dimensions are allowed.
| Width | Height | Result |
|---|---|---|
3.0 |
4.0 |
"12.00 14.00" |
1.5 |
2.5 |
"3.75 8.00" |
0.0 |
5.0 |
"0.00 10.00" |
Give related values a type
struct Rect {
width: f64,
height: f64,
}
Named fields make the two dimensions easier to identify than unnamed tuple
elements. Rect is also a distinct type: a function expecting it will not
accept an arbitrary (f64, f64) pair. The type alone does not validate the
dimensions, so this exercise states the allowed inputs separately.
Read the missing-field error
The starter constructs Rect { width: w }, leaving out height. Rust reports
E0063 because this literal does not supply every field. Add the height from
the function's h argument.
This literal does not automatically give omitted fields zero values. Rust
also has explicit ways to obtain fields from another value, such as struct
update syntax, and types can implement Default. Neither is needed here.
Access a field with rect.width. A misspelling such as rect.wdith is a
compile-time error (E0609). There is no field-level mut keyword. For this
struct's plain f64 fields, assigning directly through a local binding
requires that binding to be mutable. let rect = ... is sufficient for
this task because its methods only read the dimensions.
Mutability is not a permanent property attached to a value: it can be moved
into a mutable binding later. Other field types, such as Cell, can provide
interior mutability, but this exercise does not need it.
Read-only methods
The supplied methods live in an impl Rect block:
impl Rect {
fn area(&self) -> f64 {
self.width * self.height
}
}
&self borrows the rectangle without taking ownership. The caller can use
the same rectangle for both area() and perimeter(). Its fields store
numeric values directly, so this type needs no lifetime parameter. Structs
that store references can be useful too; those references need an explicit
lifetime, which is covered later.
Format the result
format!("{:.2} {:.2}", area, perimeter) produces one string with exactly
two digits after each decimal point and one space between the values.
Formatting rounds the computed floating-point values. It does not make the
underlying arithmetic exact: for example, 0.1 * 0.2 is not represented
exactly as the decimal number 0.02, but formats as "0.02" here.
When a variable has the same name as a field, Rect { width, height } is
shorthand for naming those values explicitly. Here the parameters are
called w and h, so width: w and height: h are appropriate.
Check the examples and the empty-size case (0.0, 0.0). Passing requires
compilation, correct output and Clippy with warnings treated as errors.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.