Строка в Rust - является неизменяемой последовательностью литералов. Тип этих данных - &str
.
fn main() {
let item1: &str = "";
let item2: &str = "0123456789";
let item3: &str = "абвгд";
print!("{} {} {}", item1, item2, item3);
}
Важной особенностью данных ссылочных функций является, то, что доступ к при попытке получить доступ к значениям будет является ошибкой при компиляции. Кроме того, в данной ссылке храниться как сама ссылка так и размер данных, которые можно получить по ссылке.
В следующем примере кода ни одна строчка не скомпилируется, т.к. значение переменной str
неизвестно в момент компиляции. Следовательно конкретное значение памяти для хранения значения не может быть выделено.
fn main() {
// let a: str;
// fn f(a: str) {}
// print!("{}", std::mem::size_of::<str>());
}
Изучим размеры этого типа данных на примере. Пожалуйста, сами поэкспериментируйте со значениями.
fn main() {
let item1: &str = "";
let item2: &str = "012345678914";
let item3: &str = "абвгд";
println!("{} {} {}", item1, item2, item3);
use std::mem::size_of_val;
println!(
"{}:{}:{}; {}:{}:{}; {}:{}:{};",
size_of_val(item1),size_of_val(&item1),size_of_val(&&item1),
size_of_val(item2),size_of_val(&item2),size_of_val(&&item2),
size_of_val(item3),size_of_val(&item3),size_of_val(&&item3)
);
}
Для работы с динамическими строками используется структура String
. Одним из способов создания экземпляра String
- вызвать
метод to_string
у статического литерала. Для добавления символа к динамической строке String
используйте метод push
:
fn main() {
let mut string: String = "Привет".to_string();
string.push(',');
string.push(' ');
string.push('R');
string.push('u');
string.push('s');
string.push('t');
string.push('!');
println!("{}", string);
}
Также как и для вектора Vec
в динамических строках можно использовать тоже методы, чтобы менять её содержимое:
fn main() {
let mut a: String = "Привет".to_string();
a.remove(0);
a.insert(0, 'П');
a.pop();
a.push('т');
print!("{}", a);
}
Рассмотрим пример получения значений ёмкости и длинны строки:
fn create_empty_stirng() -> String {
"".to_string()
}
fn add_char(string: &mut String, char_value: char) -> &String {
string.push(char_value);
string
}
fn main() {
let mut s1 = create_empty_stirng();
add_char(&mut s1, 'e');
let mut s2 = create_empty_stirng();
add_char(&mut s2, 'è');
let mut s3 = create_empty_stirng();
add_char(&mut s3, '€');
print!("{} {}; {} {}; {} {};",
s1.capacity(), s1.len(),
s2.capacity(), s2.len(),
s3.capacity(), s3.len()
);
}
В этом примере мы приминили свои знания из предыдущий глав (работа с функциями).
В стандартной библиотеке Rust есть несколько способом создать новую строку.
fn main() {
let string1 = String::new();
let string2 =String::from("");
let string3 = "".to_string();
let string4 = "".to_owned();//cloning
let string5 = format!("");
println!("{}", string1 == string2);
println!("{}", string1 == string3);
println!("{}", string1 == string4);
println!("{}", string1 == string5);
}
fn main() {
let static_string = "Hello!=>";
let string1 = String::from(static_string);
let string2 = static_string.to_string();
let string3 = static_string.to_owned();
// let _s4 = format!(static_string);
let string5 = format!("{}", static_string);
print!("({}{}{}{})", string1, string2, string3, string5);
}
Напишите программу, в которой вы покажите варианты объединения статических строк в динамический и комбинации объединения строк.
Используйте макрос format!
, метод push_str
.
Для того чтобы получить значение указателя в куче используйте функцию as_prt
:
fn main() {
//let mut s = "".to_string();
let mut s = vec![];
for _ in 0..10 {
println!("{:?} {} {}",
s.as_ptr(), s.capacity(), s.len());
s.push(55);
}
println!("{:?} {} {}: {:?}",
s.as_ptr(), s.capacity(), s.len(), s);
}
Обратите внимание, что работа с строкой String
аналогична работе с вектором.