We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Ownership III: Lifetimes, Explicitly step 6 of 22
Use lifetime elision for borrowed string results
Implement four string helpers that return borrowed slices. Remove unnecessary
lifetime annotations from the first three; give trim_prefix a signature
that ties its result to s without tying it to prefix.
pub fn longest_line(s: &str) -> &str
pub fn head_tail(s: &str) -> (&str, &str)
pub fn nth_field(s: &str, n: usize) -> &str
pub fn trim_prefix<'a>(s: &'a str, prefix: &str) -> &'a str
Required behavior
| Function | Result |
|---|---|
longest_line |
The longest line by UTF-8 byte length, with the first line winning ties. Return "" for empty input. |
head_tail |
Split at the first ASCII space, excluding that one separator. If there is no space, return (s, ""). |
nth_field |
Split on commas and return zero-based field n; return "" if it is out of range. Preserve empty fields. |
trim_prefix |
Remove one matching prefix from the start; otherwise return s unchanged. An empty prefix leaves s unchanged. |
Use str::lines semantics for longest_line: LF and CRLF end a line and are
excluded from its contents. A lone carriage return is ordinary content, and
a final line terminator does not add an extra trailing line. Byte length is
not character count: between "éé" and "abc", the former is longer
(four bytes versus three).
Other whitespace is preserved. head_tail(" a b") returns ("", "a b");
tabs are not separators. nth_field("a,,b,", 1) returns "", as does index
3. trim_prefix("abab", "ab") returns "ab", removing only one prefix.
Prefix matching is exact and case-sensitive, with no Unicode normalization.
What elision supplies
Lifetime elision fills in omitted lifetime relationships using fixed rules.
For these free functions, a single input reference lifetime can supply all
output reference lifetimes. head_tail has two outputs but one input
lifetime; nth_field also has a usize, which adds no reference lifetime.
All three therefore work without a named lifetime parameter.
trim_prefix has two independently borrowed strings. An unannotated &str
result would be ambiguous and produces E0106. The implementation returns
bytes from s, so connect only s to the output. Elision depends on the
signature, not the compiler inspecting the body to infer where you intended
the result to come from. See the reference's elision rules.
Keep the caller check
The starter includes this compile-time check:
const _: () = {
fn _pin(s: &str) -> &str {
let prefix = String::from("//");
trim_prefix(s, &prefix)
}
};
Keep it in your solution. It checks that a caller can use a short-lived
prefix while returning a slice of its longer-lived input. If both parameters
and the result share one lifetime, this call is rejected with E0515. That
signature unnecessarily restricts the caller; it does not extend the local
prefix's lifetime. A separate explicit lifetime for prefix can express the
same independence, but leaving it elided is simpler here.
Clippy's needless_lifetimes flags removable annotations in the first three
functions. Warnings are denied by the grader. The starter also has unfinished
bodies, so implement them as well as fixing the signatures. The preserved
caller check tests a lifetime relationship that ordinary output tests cannot
establish on their own.
Use string splitting and prefix methods to keep slice boundaries valid for
UTF-8. To keep the first longest line, update the current best only for a
strictly greater byte length; max_by_key on the original order would choose
the last tied maximum.
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.