String Methods
Вывод строк
- Макрос
println!позволяет вывести строку в поток stdout;
// println!("Hello there!\n");
// раскрывается в такой код:
use std::io::{self, Write};
io::stdout().lock().write_all(b"Hello there!\n").unwrap();- Макрос
dbg!()позволяет вывести переменные и структуры в поток stdout;
split()
Метод split: разбивает строку на части по указанному разделителю и возвращает итератор. Разделитель может быть символом, строкой или даже пробелом. В том числе можно делить по нескольким символам разом:
let text = String::from("the_stealth-warrior");
let parts = text.split(['-', '_']).collect::<Vec<&str>>();
// collect собирает в коллекцию типа вектор
for part in parts {
println!("{}", part);Другие методы разбивки
split_whitespace()
Разбивает по любым пробельным символам (пробелы, табы, переносы строк).
let text = "apple banana\ncherry";
let words: Vec<&str> = text.split_whitespace().collect();
println!("{:?}", words); // ["apple", "banana", "cherry"]
splitn(n, delimiter)
Разбивает только на первые n частей:
let text = "a,b,c,d";
let parts: Vec<&str> = text.splitn(3, ",").collect();
println!("{:?}", parts); // ["a", "b", "c,d"]
Склеивание строк (конкатенация)
В Rust надо учитывать, что String владеет памятью, а &str — нет.
Оператор +
String + &str работает, но забирает владение у первой строки.
let s1 = String::from("hello");
let s2 = " world";
let res = s1 + s2; // res == "hello world", s1 больше нельзя использовать
push_str()
Метод push_str() добавляет &str к существующей String, не забирая владение (строка должна быть mut).
let mut s = String::from("hello");
s.push_str(" world"); // s == "hello world"
push()
Добавляет один символ:
let mut s = String::from("hello");
s.push('!'); // s == "hello!"
join()
Склеивает коллекцию (вектор) строк с разделителем:
let words = vec!["apple", "banana", "cherry"];
let res = words.join(", "); // res == "apple, banana, cherry"
format!()
Мощный способ объединять строки. Макрос format! позволяет сформировать строку и вернуть из функции;
fn output_string(t: &String) -> String {
format!("Hello, {}",t) // возврат сформированной строки
}При этом format!() позволяет конвертировать формат чисел.
Decimal -> HEX:
fn rgb(r: i32, g: i32, b: i32) -> String {
format!(
"{:02X}{:02X}{:02X}", // конвертация dec -> 2 символа UPPER hex
// {:02x} => конвертация в lower hex.
r.clamp(0, 255), // clamp задаёт валидный диапазон чисел
g.clamp(0, 255), // аналог == g.min(255).max(0)
b.clamp(0, 255))}
fn main() {
println!("{}", rgb(1, 2, 3)); // 010203
println!("{}", rgb(255, 255, 255)); // FFFFFF
println!("{}", rgb(-20, 275, 125)); // 00FF7D
}Decimal -> Binary:
let b = format!("{:b}", 42);
println!("{}", b); // 101010
Другие популярные методы работы со строками
- Метод
len()выдаёт длину строки в байтах; - Метод
is_empty()проверят, что строка непустая; - Метод
contains()ищет одну строку в другой строке; - Метод
replace(from,to)заменяет часть строки на другую и выдаёт результат;
fn main() {
let mut a = String::from("Wonderful RUST World");
println!("Hello{}!", output_string(&a)); // вывод строки
println!("String is empty? {}", a.is_empty());
println!("String length: {}", a.len());
println!("Does string contain 'Hello'? {}", a.contains("Hello"));
}
Пример задачи
Нахождение закономерностей в структурах со строками
В примере мы передаём вектор из строк. Далее, анализируем его по частям:
fn likes(names: &[&str]) -> String {
match names {
[] => "no one likes this".to_string(),
[a] => format!("{} likes this", a),
[a, b] => format!("{} and {} like this", a, b),
[a, b, c] => format!("{}, {} and {} like this", a, b, c),
[a, b, other @ ..] => format!("{}, {} and {} others like this", a, b, other.len()),
}
}