We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ownership I: Moves, Copy, Clone, Drop step 9 of 20
Giving ownership back
Implement two functions that take ownership of a string and return owned results:
pub fn split_owned(text: String, sep: char) -> (Vec<String>, usize)
pub fn first_owned(text: String) -> String
Split the text and count its characters
split_owned returns the pieces separated by sep, plus the number of
Unicode scalar values in the original text, including separators.
This is what text.chars().count() measures. It is not a byte count or
necessarily the number of visible symbols: a letter followed by a combining
accent contributes two scalar values.
| Text and separator | Pieces | Count |
|---|---|---|
"a,b,c", ',' |
["a", "b", "c"] |
5 |
"", ',' |
[""] |
0 |
",a,", ',' |
["", "a", ""] |
3 |
"héllo,wörld", ',' |
["héllo", "wörld"] |
11 |
Keep empty pieces at the start, end and between adjacent separators.
A separator is a Rust char, so it may be a non-ASCII scalar value.
Keep the supplied shatter helper and its signature:
fn shatter(text: String, sep: char) -> Vec<String>
Call it to produce the pieces. It takes ownership of text, so any
measurement that uses text must happen before that call.
let pieces = shatter(text, sep);
(pieces, text.chars().count()) // Error: text has already moved.
This use after a move produces E0382. Compute the count first, then return
the pieces and count together. There is no need to clone the input just to
measure it.
Return the first word as owned text
first_owned returns the first nonempty whitespace-separated word, or an
empty String if there is none. Use the whitespace rules of
split_whitespace(), including Unicode whitespace. Do not include leading
or trailing whitespace in the result.
For example, " hello world " gives "hello", "ünïcödé test" gives
"ünïcödé", and an empty or whitespace-only input gives "".
The starter's helper tries to return a slice into a string it owns:
fn first_slice(text: String) -> &str {
text.split_whitespace().next().unwrap_or("")
}
Its output reference has no input lifetime to borrow from, producing
E0106. Changing the return type to &'static str does not repair the
body: it then produces E0515 because the returned word borrows text,
which is dropped when the function returns. A lifetime annotation does not
keep that buffer alive.
Change or remove this helper. Convert the selected slice to an owned
String while text is still available, then return it. The caller owns
that result independently of the input's original buffer.
Moving an owner differs from copying a slice
Returning an existing String transfers ownership without requiring a copy
of its contents. Converting a nonempty &str with to_string() creates
owned storage and copies the selected bytes. An empty result does not
require a buffer allocation. Returning owned data does not universally
require a fresh allocation; here the straightforward solution copies a
word out of the input.
A different API could borrow caller-owned text instead:
fn first_borrowed(text: &str) -> &str {
text.split_whitespace().next().unwrap_or("")
}
That slice must remain valid for its uses, so the caller must keep the borrowed storage alive. This exercise requires the owned signatures above.
Use string iterators to handle UTF-8. Byte-range slicing can also be valid when both bounds are character boundaries, but arbitrary byte offsets can panic. Passing requires compilation, correct outputs 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.