We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ownership I: Moves, Copy, Clone, Drop step 8 of 20
Ownership through function calls
Pair labels with weights and return a header followed by one summary per pair.
Repair summarise using the supplied helpers without changing their signatures
or behavior.
pub fn summarise(labels: Vec<String>, weights: Vec<i64>) -> Vec<String>
Output format
The first string is "<label-count>x<weight-count>", using the original
lengths of both input vectors. Include this header even when there are no pairs.
Pair inputs in their original order and stop at the shorter vector. For each
pair, append "<label>=<score>|<char-count>|<weight>".
| Helper | Input and result |
|---|---|
consume_label(label: String) -> usize |
Takes ownership of a label and counts its Unicode scalar values with chars().count(). |
score(weight: i64) -> i64 |
Returns weight * 2 + 1. |
tag(label: String, score: i64) -> String |
Takes ownership of a label and formats "<label>=<score>". |
Call all three helpers for each pair. Labels may be empty or contain Unicode,
whitespace, or separator characters. Preserve their text exactly; do not trim
or escape it. The character count is neither a byte count nor necessarily the
number of visible characters: "é" has one scalar value, while "e\u{301}"
has two.
Weights used in pairs are in -4611686018427387904..=4611686018427387903,
so both the multiplication and addition in score fit in i64.
For example:
labels = ["ada", "bo", "unused"]
weights = [3, 0]
result = ["3x2", "ada=7|3|3", "bo=1|2|0"]
The header reports all three labels, but the unmatched label produces no pair
string. An empty label vector with weights [1, 2] produces only ["0x2"].
Measure before consuming the vectors
labels.into_iter() takes ownership of the label vector. Passing weights
directly to zip also consumes that vector through its IntoIterator
implementation. Reading either vector's length afterward causes E0382.
Construct the header before the loop, while both vectors are available. Cloning entire vectors just to read their lengths would duplicate data that the header does not need.
Give each consuming helper a label
The starter moves label into tag, then tries to pass it to consume_label.
That is another use-after-move error. Both helpers accept an owned String,
and neither returns the input string to the caller.
A straightforward repair is to pass label.clone() to one helper and move
the original into the other. This creates a separate owned string for the
second call. Cloning is allowed in this exercise; avoid cloning either whole
input vector.
The same issue does not arise for weight. i64 implements Copy, so passing
it by value to score leaves the caller's variable usable. A by-value parameter
moves a non-Copy value such as String, but copies a Copy value such as
i64.
Here is a separate example of the distinction:
fn text_len(text: String) -> usize {
text.chars().count()
}
fn doubled(number: i64) -> i64 {
number * 2
}
fn main() {
let text = String::from("hi");
let length = text_len(text.clone());
assert_eq!(length, 2);
assert_eq!(text, "hi");
let number = 3;
assert_eq!(doubled(number), 6);
assert_eq!(number, 3);
}
In APIs you design yourself, a helper that only reads text can often accept
&str instead. That lets callers lend the text without transferring ownership
or making a second owned string. The consuming signatures here are fixed so
you can practice arranging calls around ownership.
A passing submission must compile, pass the tests, and pass
clippy -D warnings. Leaving a supplied private helper unused can trigger
dead_code, but that lint alone does not prove that every pair used every
helper as requested.
Loading visualization…
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.