Strings

String

std

/// This example demonstrates various ways to work with strings in Rust.
fn main() {
    // `String` is a growable, heap-allocated data structure that is
    // Unicode, not ASCII.
    let mut s1 = String::from("hello");

    // `push_str` appends a string slice to a `String`.
    // `String` can be mutated.
    s1.push_str(", world!"); // `String` can be mutated.
    s1.clear(); // Empties the String, making it equal to "".

    // Alternative initialization from string literals:
    // `to_string` is available on any type that implements
    // the `Display` trait.
    let s2 = "initial contents".to_string();

    // Concatenation:
    // Note: s1 has been moved here and can no longer be used afterwards.
    // The `+` operator takes ownership of the first string and appends
    // a string slice to it.
    let s3 = s1 + &s2;
    // ERROR let s = format!("{s1}-{s2}-{s3}");

    // String slice:
    // Contains the first 4 bytes of the string.
    let _s: &str = &s3[0..4];
    // Caution:
    // If we were to try to slice only part of a unicode
    // character's bytes, Rust would panic at runtime.
    // String slices are always valid UTF-8.
    // This is because Rust only allows slicing at character boundaries.

    // Iteration
    for c in "Зд".chars() {
        println!("{c}");
    }
    for b in "Зд".bytes() {
        println!("{b}");
    }
}

String Formatting; Placeholders

std

//! Example of using the `println!` macro.

fn main() {
    let x = 5;
    let y = 10;
    // { } are placeholders.
    println!("x = {x} and y + 2 = {}", y + 2);
}

Use {:?} to use the std::fmt::Debug⮳ output format (annotate type with #[derive(Debug)] ) or {:#?} for pretty print.

Also use dbg!(&rect1); for debug output (returns ownership of the expression's value).

Concatenate Strings

std

Here are several common methods to concatenate Strings⮳:

//! This example demonstrates various ways to concatenate strings in Rust.
//! It includes examples using `concat`, `join`, `format`, `push_str`, `+`, and
//! external macros.
#[macro_use(concat_string)]
extern crate concat_string;

#[macro_use(concat_strs)]
extern crate concat_strs;

static DATE: &str = "2024-01-15";
static T: &str = "T";
static TIME: &str = "12:00:09Z";

fn main() {
    // Using `concat` on a slice of string slices.
    let _datetime = &[DATE, T, TIME].concat();

    // Using `join` with a separator on a slice of string slices.
    let _datetime = &[DATE, TIME].join(T);

    // Using `join` with an empty separator on a slice of string slices.
    let _datetime = &[DATE, T, TIME].join("");

    // Using `join` with an empty separator on a slice of string slices.
    let _datetime = &[DATE, T, TIME].join("");

    // Using `iter().copied().collect()` to concatenate a slice of string
    // slices.
    let list = [DATE, T, TIME];
    // let _datetime: String = list.iter().map(|x| *x).collect();
    let _datetime: String = list.iter().copied().collect();

    // Using `iter().copied().collect()` to concatenate a vector of string
    // slices.
    let list = vec![DATE, T, TIME];
    // let _datetime: String = list.iter().map(|x| *x).collect();
    let _datetime: String = list.iter().copied().collect();

    // Using `format!` macro with positional arguments.
    let _datetime = &format!("{}{}{}", DATE, T, TIME);

    // Using `format!` macro with named arguments (Rust 1.58+).
    let _datetime = &format!("{DATE}{T}{TIME}");

    // Using `push_str` to build a string incrementally.
    let mut datetime = String::new();
    datetime.push_str(DATE);
    datetime.push_str(T);
    datetime.push_str(TIME);

    // Using `push` on a vector of strings and then `join`.
    let mut datetime = Vec::<String>::new();
    datetime.push(String::from(DATE));
    datetime.push(String::from(T));
    datetime.push(String::from(TIME));
    let _datetime = datetime.join("");

    // Using `push_str` with pre-allocated capacity.
    let mut datetime = String::with_capacity(20);
    datetime.push_str(DATE);
    datetime.push_str(T); // or 'T'
    datetime.push_str(TIME);

    // Using `+` operator with `String::from` for each part.
    let _datetime =
        &(String::from(DATE) + &String::from(T) + &String::from(TIME));

    // Using `+` operator with `String::from` for the first part and string
    // slices for the rest.
    let _datetime = &(String::from(DATE) + T + TIME);

    // Using `+` operator with `to_owned` for the first part and string slices
    // for the rest.
    let _datetime = &(DATE.to_owned() + T + TIME);

    // Using `+` operator with `to_string` for the first part and string slices
    // for the rest.
    let _datetime = &(DATE.to_string() + T + TIME);

    // Using the `concat_string!` macro.
    let _datetime = concat_string!(DATE, T, TIME);

    // Using the `concat_strs!` macro.
    let datetime = &concat_strs!(DATE, T, TIME);

    println!("{}", datetime);
}

Examples from concatenation_benchmarks-rs⮳.

Related Data Structures

  • Slices.
  • Vectors.
  • COW.

String Manipulation

  • Regex (Regular Expressions).
  • Parsing.
  • Text Processing.
  • String Parsing.
  • String Concatenation.

Related Topics

  • Algorithms.
  • Encoding.
  • Internationalization.
  • Localization.
  • Search.
  • Rust Search Engines.
  • Template Engine.
  • Text Layout.
  • Unicode handling.
  • Value Formatting.
  • Working with Other Strings (CString, OsString).