techmore.in

Rust - Strings

In Rust, working with strings can seem complex at first because Rust offers multiple string types with different use cases. Here's a comprehensive overview of how strings work in Rust:

1. String Types in Rust

Rust primarily has two string types:

  • String: A growable, heap-allocated string.
  • &str (string slice): A borrowed reference to a string, which can point to a part of a String or a string literal.

String (String)

  • Owned, heap-allocated, and mutable.
  • Used when you need to modify the string or when the string needs to be owned by a variable.
rust
fn main() { let mut s = String::from("Hello, "); s.push_str("world!"); // Modifies the string println!("{}", s); }

String Slice (&str)

  • Immutable reference to a string, either part of a String or a string literal.
  • Used when you need to borrow a string or when working with string literals.
rust
fn main() { let s = "Hello, world!"; // string literal, type &str let part = &s[0..5]; // string slice, type &str println!("{}", part); }

2. Creating Strings

You can create strings in several ways:

From a String Literal

rust
fn main() { let s = String::from("Hello, Rust!"); println!("{}", s); }

Using to_string()

rust
fn main() { let s = "Hello, Rust!".to_string(); println!("{}", s); }

With String::new()

Creates an empty String.

rust
fn main() { let mut s = String::new(); s.push_str("Hello, Rust!"); println!("{}", s); }

3. String Operations

Concatenation

You can concatenate strings using push_str, push, or the + operator.

  • push_str: Appends a string slice to a String.
rust
fn main() { let mut s = String::from("Hello, "); s.push_str("Rust!"); println!("{}", s); }
  • push: Appends a single character to a String.
rust
fn main() { let mut s = String::from("Hello"); s.push('!'); println!("{}", s); }
  • + Operator: Concatenates strings, but the left-hand operand must be a String.
rust
fn main() { let s1 = String::from("Hello, "); let s2 = "Rust!"; let s3 = s1 + s2; // s1 is moved and can no longer be used println!("{}", s3); }

Formatting with format!

The format! macro is used to concatenate strings without taking ownership:

rust
fn main() { let s1 = String::from("Hello, "); let s2 = String::from("Rust!"); let s3 = format!("{}{}", s1, s2); println!("{}", s3); // s1 and s2 are still valid }

4. String Slices

String slices (&str) allow you to reference a part of a string without taking ownership.

rust
fn main() { let s = String::from("Hello, Rust!"); let hello = &s[0..5]; // Slice containing "Hello" let rust = &s[7..11]; // Slice containing "Rust" println!("{}, {}", hello, rust); }

5. String Length and Capacity

  • Length: Number of bytes (not necessarily characters) in the string.
rust
fn main() { let s = String::from("Hello, Rust!"); println!("Length: {}", s.len()); }
  • Capacity: Total amount of memory allocated for the String.
rust
fn main() { let s = String::with_capacity(20); println!("Capacity: {}", s.capacity()); }

6. Iterating Over Strings

Rust strings are UTF-8 encoded, so iterating over them can be done by bytes, characters, or grapheme clusters (from an external crate).

By Characters

rust
fn main() { let s = "Hello, Rust!"; for c in s.chars() { println!("{}", c); } }

By Bytes

rust
fn main() { let s = "Hello, Rust!"; for b in s.bytes() { println!("{}", b); } }

7. String Methods

Rust provides several methods to manipulate and inspect strings:

  • is_empty: Checks if the string is empty.
  • contains: Checks if a substring is present.
  • replace: Replaces all matches of a pattern.
  • split: Splits the string based on a pattern.
  • trim: Removes whitespace from both ends of the string.

Example of Some Methods:

rust
fn main() { let s = String::from(" Rust is great! "); println!("Is empty: {}", s.is_empty()); // false println!("Contains 'great': {}", s.contains("great")); // true println!("Trimmed: '{}'", s.trim()); // "Rust is great!" println!("Replaced: {}", s.replace("great", "awesome")); // "Rust is awesome!" for word in s.split_whitespace() { println!("{}", word); } }

Summary

  • String: Owned, heap-allocated, and mutable string.
  • &str: Immutable borrowed string slice, often used with string literals.
  • Operations: Concatenation, slicing, iteration, and various string methods allow you to manipulate strings effectively.
  • UTF-8: Rust strings are UTF-8 encoded, which impacts how you can work with them.

This should give you a solid understanding of how to work with strings in Rust!