We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ownership I: Moves, Copy, Clone, Drop step 10 of 20
Partial moves: taking one field and leaving the rest
Build a record, replace an empty label, then take its fields apart to format one output string per input.
pub fn repack(records: Vec<(i64, String, Vec<String>)>) -> Vec<String>
The grader supplies this type. Do not redefine it or add Clone or Drop:
struct Record {
id: i64,
label: String,
tags: Vec<String>,
}
Required behavior
Each input tuple contains (id, label, tags). Return strings in input order
using the format "<id>:<label>[<joined-tags>]".
Replace only an empty label with "anon". Preserve every other label,
including whitespace and Unicode. Join tags with +, preserving their order
and contents. An empty tag list produces empty brackets; empty tags remain
part of the join. Do not escape punctuation in labels or tags.
(1, "a", ["x", "y"]) -> "1:a[x+y]"
(7, "", ["a"]) -> "7:anon[a]"
(0, "z", []) -> "0:z[]"
(2, " ", ["", "x"]) -> "2: [+x]"
An empty input returns an empty vector. IDs may be any i64 value; format
them without performing arithmetic.
Practice field moves
For each tuple:
- Construct
Record { id, label, tags }. - If its label is empty, rebuild it with
Record { label: String::from("anon"), ..r }. - Move
labelout, then movetagsout, then readid. - Format the result from those local values.
Use this sequence and struct update syntax for the exercise. Avoid cloning the fields. Output checks alone do not prove that a solution follows these implementation requirements.
Moving a non-Copy field leaves the record partially moved. Other fields
remain available, but the whole record cannot be used until the missing field
has been restored. Reading r.id copies its i64; moving r.tags transfers
its vector. A remaining field does not have to implement Copy to be moved
out separately.
What the starter gets wrong
The starter moves r.label into a local named label before its conditional.
Its else branch then tries to move the whole r, causing E0382.
The struct update in the other branch is not the problem. It explicitly
supplies a new label, so ..r only needs the remaining id and tags fields.
Struct update does not require every source field to be present.
There is also an output mistake: the starter formats the old local label,
so rebuilding the record alone would not make the output use "anon".
Apply the replacement first, then extract the fields from the resulting record.
Understand struct update
Record { label: new_label, ..r } takes only unspecified fields from r.
It copies id because i64 is Copy, and moves tags because Vec<String>
is not. It does not read or move r.label.
This complete example shows that replacing an already-moved field is valid:
struct Item {
name: String,
tags: Vec<String>,
}
fn main() {
let item = Item {
name: String::from("old"),
tags: vec![String::from("kept")],
};
let old_name = item.name;
let rebuilt = Item {
name: String::from("new"),
..item
};
assert_eq!(old_name, "old");
assert_eq!(rebuilt.name, "new");
assert_eq!(rebuilt.tags, ["kept"]);
}
By contrast, trying to move item as a whole after extracting item.name
would fail. The difference is which fields the operation needs.
Keep field shorthand and destructor rules separate
When a field and local variable have the same name, id is shorthand for
id: id in a struct initializer. Clippy's redundant_field_names lint rejects
the starter's repeated names when warnings are denied.
Record does not implement Drop, which permits these direct moves of its
non-Copy fields. Adding a Drop implementation would make those moves fail
with E0509: the destructor needs a valid whole record. Copying an i64 field
is different because it leaves the original field present. The absence of a
Clone implementation on Record does not make its individual strings or
vector unclonable; avoiding those clones is part of this exercise.
A passing submission must compile, pass the tests, and pass
clippy -D warnings.
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.