Rust Fundamentals · 15 XP Pro

Strings

Rust has two main text types: &str, a borrowed view of text, and String, an owned, growable buffer. Build a String with String::new(), String::from("hi") or "hi".to_string(), then grow it:

let mut s = String::from("Hello");
s.push_str(", world");   // append a &str
s.push('!');             // append one char
let line = format!("{s} ({} bytes)", s.len());

format! works like println! but returns a String instead of printing.

All text is UTF-8, so a character can take more than one byte. That is why you cannot index a string with s[0]. Instead pick the view you want:

  • s.len() counts bytes.
  • s.chars() iterates over characters (Unicode scalar values).
  • s.chars().count() counts characters.
  • s.bytes() iterates over raw bytes.
let word = "naïve";
assert_eq!(word.len(), 6);            // ï takes two bytes
assert_eq!(word.chars().count(), 5);

Your task

Everything must be pub. Write:

  1. pub fn greeting(name: &str) -> String: returns "Hello, {name}!". Try format!.
  2. pub fn join_words(words: &[&str]) -> String: joins the words with single spaces, with no leading or trailing space. Build it with push_str. An empty slice gives an empty string.
  3. pub fn count_chars_and_bytes(s: &str) -> (usize, usize): the number of characters, then the number of bytes.
  4. pub fn vowel_count(s: &str) -> usize: how many of the characters are one of a e i o u, upper or lower case. Loop over s.chars().

Next lesson →

Sign in to run your code. It's free.