Перейти к основному содержанию

16. Строки (String)

Напомним, что в Rust существует символьный тип данных char, фиксированная строка &str и строковый объект String. Переменная типа String, в отличии от фиксированной строки, может быть не задана до компиляции и такая переменная изменяемая. Строковый объект размещается в куче.

Строковый тип не является частью основного языка Rust. Он определяется как общедоступная структура в стандартной библиотеке.

String – это наращиваемая коллекция. Объект строки похож на уже изученный нами вектор, только предназначенный сугубо для символов UTF-8. 

Создать объект строки можно несколькими способами:

String::new();		// пустая строка
String::from("Пример строки");
"Ещё пример".to_string;	// конвертирует &str в String

Доступ к элементам строки

С этими строками всё крайне запутано. Различные символы кодируются разным количеством байт, а в языках буквы могут быть представлены разным количеством символов.

len() – возвращает не количество символов в строке, а количество байтов в памяти, занятых объектом String.

fn main() {
	let s1: String = "Day".to_string();
	let s2: String = "День".to_string();
	println!("Длина {} {} байт",s1, s1.len());
	println!("Длина {} {} байт",s2, s2.len());
}
Результат: Длина Day 3 байт Длина День 8 байт

Rust учитывает все нюансы работы с текстом для избежания ошибок вашей программы в будущем, но из-за этого всё немного усложняется.

Компилятор Rust не позволяет нам обращаться к символам по индексу, как это мы могли делать в векторах. Подробнее здесь: https://doc.rust-lang.org/book/ch08-02-strings.html#internal-representation.

Вот ещё несколько методов работы со строками:

contains("sub_str") – осуществляет поиск подстроки в строке. Возвращает булево значение.

replace("text_from", "text_to") – выдаёт новую строку в которой заменяет одну часть текста на другую.

fn main() {
	let before: String = "Бег на месте".to_string();
	if before.contains("на месте") {
		let after: String = before.replace("на месте", "трусцой");
		println!("{}", after);
	}
}
Результат: Бег трусцой

В этом примере мы сначала проверили содержится ли строка на месте в исходной, а затем заменили её на другую.

push() – добавляет символ в конец строки.

push_str() – добавляет фиксированную строку в конец строки.

fn main() {
	let mut str = "Star".to_string();
	println!("{}", str);
	str.push('s');
	println!("{}", str);
	str.push_str(" and moon");
	println!("{}", str);
}
Результат: Star Stars Stars and moon

trim() – выдаёт новую строку в которой удаляет пробелы в начале и в конце.

fn main() {
    let s: String = "  Пример строки   с пробелами  ".to_string();
    let s1 = s.trim();
    println!("-{}-", s);
    println!("-{}-", s1);
}
Результат: - Пример строки с пробелами - -Пример строки с пробелами-

Итерация по строкам

Строки можно использовать в цикле с помощью специальных методов.

chars() – разбивает строку посимвольно и возвращает итератор

fn main() {
	let my_str ="Не бойся ошибаться".to_string();
	for s in my_str.chars() {
		print!("{} * ", s)
	}
}
Результат: Н * е * * б * о * й * с * я * * о * ш * и * б * а * т * ь * с * я *

split_whitespace() – разбивает строку по пробелам и возвращает итератор.

fn main() {
	let my_str =
		"Не рискуя, мы рискуем в сто раз больше."
		.to_string();
	for s in my_str.split_whitespace() {
		println!("{}", s)
	}
}
Результат: Не рискуя, мы рискуем в сто раз больше.

split(string) – разбивает строку по указанным символами или фиксированным строкам возвращает итератор.

fn main() {
	let my_str = "Твори и ошибайся. В этом жизнь.".to_string();
	for s in my_str.split('.') {    // разбиваем по символу точка
		println!("*{}*", s)
	}
	println!("");
	for s in my_str.split(". ") {    // разбиваем по сроке точка и пробел
		println!("*{}*", s)
	}
}
Результат: *Твори и ошибайся* * В этом жизнь* ** *Твори и ошибайся* *В этом жизнь.*

Сложение строк

К строке можно присоединить фиксированную строку.

fn main() {
	let s1: String = "Утро".to_string();
	let s2: &str = "великолепное";
	let s3 = s1 + " " + s2; 
	println!("{}",s3);
}
Результат: Утро великолепное

А вот, с присоединением объекта строки чуть сложнее.

fn main() {
	let s1: String = "Утро".to_string();
	let s2: String = "великолепное".to_string();
	let s3 = s1 + " " + &s2; // передаем ссылку на строку
	println!("{}",s3);
}
Результат: Утро великолепное
Опять мы затронули тему ссылок при использовании переменной s2. Эту тему рассмотрим в следующем курсе.

Срезы строк

Нас ждут в следующем курсе.

Для просмотра заданий и решений, а также публикации своих решений необходимо зарегистрироваться на сайте.

Всё бесплатно, мы просто хотим с вами познакомиться и понять насколько актуально то, что мы делаем.

© Клют И. А., 2022. Копирование контента возможно только с письменного разрешения автора.