🦀 Rust

Строки и работа с текстом в Rust 1.75: подробное руководство

Строки и работа с текстом в Rust

Введение: Зачем нужны строки?

Представь, что ты пишешь сообщение другу, создаешь название для NFT-токена или придумываешь подпись к посту в соцсетях. Везде, где есть текст, компьютер должен уметь его хранить и обрабатывать. В Rust для этого есть специальный тип данных — строка (String). Строки позволяют хранить слова, предложения и целые тексты, а также выполнять с ними разные операции: находить части текста, считать символы, объединять строки и многое другое.

Основной синтаксис: как работать со строками

Создание строки

Самый простой способ создать строку — использовать функцию String::from() или метод .to_string():

let название = String::from("Мой первый NFT");
let хештег = "программирование".to_string();
println!("{}", название); // Мой первый NFT
println!("{}", хештег);   // программирование

Длина строки (сколько символов)

Чтобы узнать, сколько символов в строке, используй метод .len():

let текст = "Привет, мир!";
println!("Длина строки: {}", текст.len()); // Длина строки: 12

Объединение строк (конкатенация)

Строки можно складывать с помощью + или форматировать с помощью format!:

let часть1 = String::from("Super");
let часть2 = String::from("Gadget");
let полное = часть1 + &часть2; // используем & перед второй строкой
println!("{}", полное); // SuperGadget

// Более удобный способ с format!
let имя = "X";
let версия = 7;
let результат = format!("{}{}", имя, версия);
println!("{}", результат); // X7

Извлечение части строки (срез)

Чтобы взять часть строки, используй квадратные скобки с диапазоном. Важно: в Rust нужно указывать границы по байтам, а не по символам. Для простых латинских букв и цифр это одно и то же:

let хештег = "#ЛучшийДень";
// Берем первые 8 символов (символ # + 7 букв "ЛучшийД")
let часть = &хештег[0..8];
println!("{}", часть); // #ЛучшийД

Переворот строки (задом наперед)

Для переворота строки нужно собрать символы в обратном порядке с помощью .chars().rev():

let оригинал = "Привет";
let перевернутая: String = оригинал.chars().rev().collect();
println!("{}", перевернутая); // тевирП

Разбор типичных задач

Задача «Хештег» (обрезка строки)

У нас есть длинный хештег, например #ЛучшийДеньДляПрограммирования. Нужно взять первые 10 символов (считая решетку).

use std::io;

fn main() {
    println!("Введите хештег:");
    let mut хештег = String::new();
    io::stdin().read_line(&mut хештег).expect("Ошибка чтения");
    let хештег = хештег.trim(); // убираем лишние пробелы и перенос строки
    
    // Берем первые 10 символов
    let короткий = &хештег[..10];
    println!("Короткий хештег: {}", короткий);
}

Задача «Песня» (подсчет слов)

Дана строка с текстом песни. Нужно посчитать количество слов (слова разделены пробелами).

use std::io;

fn main() {
    println!("Введите текст песни:");
    let mut текст = String::new();
    io::stdin().read_line(&mut текст).expect("Ошибка чтения");
    let текст = текст.trim();
    
    // Разделяем строку по пробелам и считаем количество частей
    let слова: Vec<&str> = текст.split(' ').collect();
    let количество = слова.len();
    println!("Количество слов: {}", количество);
}

Задача «Обратное сообщение» (переворот строки)

Пользователь вводит фразу, программа выводит её задом наперед.

use std::io;

fn main() {
    println!("Введите сообщение для переворота:");
    let mut сообщение = String::new();
    io::stdin().read_line(&mut сообщение).expect("Ошибка чтения");
    let сообщение = сообщение.trim();
    
    let перевернутое: String = сообщение.chars().rev().collect();
    println!("Перевернутое сообщение: {}", перевернутое);
}

Частые ошибки новичков

  • Ошибка 1: Попытка изменить строку через индекс
    let s = String::from("привет"); s[0] = 'П'; // Ошибка!
    В Rust строки нельзя изменять по индексу. Используй replace или собирай новую строку.
  • Ошибка 2: Забыть про & при сложении строк
    let a = String::from("A"); let b = String::from("B"); let c = a + b; // Ошибка!
    Правильно: let c = a + &b;
  • Ошибка 3: Использовать .len() для строк с кириллицей
    "Привет".len() вернет 12 (каждая буква занимает 2 байта), а не 6. Для подсчета символов используй "Привет".chars().count().
  • Ошибка 4: Выход за границы среза
    Если попытаться взять срез не по границе символа (например, &s[0..1] для кириллицы), программа упадет с ошибкой. Всегда используй .chars() для работы с символами.

Итоговый пример: решаем задачу «Статья»

У нас есть текст статьи. Нужно вывести последние 50 символов (заключительную часть).

use std::io;

fn main() {
    println!("Введите текст статьи:");
    let mut статья = String::new();
    io::stdin().read_line(&mut статья).expect("Ошибка чтения");
    let статья = статья.trim();
    
    // Находим длину в байтах
    let длина = статья.len();
    
    // Берем последние 50 символов (если статья длиннее 50 символов)
    if длина > 50 {
        // Начинаем с (длина - 50) байта
        let заключение = &статья[длина-50..];
        println!("Заключительная часть статьи:");
        println!("{}", заключение);
    } else {
        println!("Статья слишком короткая, вывожу целиком:");
        println!("{}", статья);
    }
}

Как это работает: Мы получаем длину строки в байтах, затем отнимаем 50, чтобы получить начало последних 50 байт. Если строка короче 50 символов — просто выводим её целиком. Обрати внимание: этот пример работает корректно для текстов на латинице. Для кириллицы нужно использовать .chars() и собирать строку посимвольно — это тема следующего урока!