tezvyn:

What type replaces String for read-only function parameters in Rust?

AI-drafted, machine-checkedSource: doc.rust-lang.orgintermediate
WHAT IT TESTS

Knowledge of Rust's read-only string view and API ergonomics.

ANSWER OUTLINE

Use &str; it borrows without ownership, accepts literals and String via coercion, and avoids clones.

WHAT THIS TESTS: This question probes your understanding of Rust ownership ergonomics and API design. Specifically, it checks whether you know that &str is the idiomatic view type for read-only string data and whether you can articulate the practical usability benefits over an owned String or a borrowed &String.

A GOOD ANSWER COVERS: First, state that &str is the correct parameter type. Second, explain that &str is a slice referencing valid UTF-8 bytes and does not take ownership, so the caller keeps their String. Third, describe flexibility: because String implements Deref<Target=str>, a &String coerces to &str automatically, meaning the function accepts both heap-allocated strings and string literals like hello without cloning. Fourth, note that this choice hides implementation details; the caller does not need to know whether the original data was a String, a static literal, or an OsString converted to a str. Fifth, mention that &str prevents unnecessary allocations and makes the function usable in no-std or embedded contexts where String may be unavailable.

COMMON WRONG ANSWERS: Suggesting &String is the most frequent mistake. This locks out string literals and forces callers who have a &str to construct a new String just to pass it in. Another red flag is saying you should clone the String inside the function to avoid ownership issues; this misses the point of zero-cost borrowing. Some candidates also confuse &str with String and claim the difference is only performance, failing to mention the deref coercion and API contract aspects.

LIKELY FOLLOW-UPS: An interviewer might ask what happens if you need to mutate the string, leading to a discussion of &mut String versus returning a new String. They might also ask about OsStr or CString and when those are preferable to &str. Another common follow-up is asking you to write a function that takes either a String or &str and explain why Into<Cow<str>> or generics with AsRef<str> could be useful for APIs that need to accept both without forcing the caller to decide.

ONE CONCRETE EXAMPLE: Imagine a function count_vowels that takes a string and returns a usize. If the signature is fn count_vowels(s: String) -> usize, then calling it with let text = aeiou; requires count_vowels(text.to_string()), which allocates. If the signature is fn count_vowels(s: &str) -> usize, the same call becomes count_vowels(text) with zero allocation. A caller with an owned String named buffer can still write count_vowels(&buffer) because the compiler inserts the deref coercion from &String to &str automatically.

Read the original → doc.rust-lang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.