Общие коллекции
Эта тема требует отдельного изучения и как факт я намереваюсь сделать перевод reference и стандартной библиотеки rust
Это в общей коллекции представлено как доступные коллекции
- Sequences: Vec, VecDeque, LinkedList
- Maps: HashMap, BTreeMap
- Sets: HashSet, BTreeSet
- Misc: BinaryHeap
Вектор
Векторы позволяют хранить более одного значения в единой структуре данных, хранящей элементы в памяти один за другим. Векторы могут хранить данные только одного типа.
fn main() { let v: Vec<i32> = Vec::new(); } //или fn main() { let v = vec![1, 2, 3]; //это через макрос с инициализацией значений }
Векторы можно push
#![allow(unused)] fn main() { let mut v = Vec::new(); v.push(5); v.push(6); v.push(7); v.push(8); }
Чтение векторов
#![allow(unused)] fn main() { let v = vec![1, 2, 3, 4, 5]; let third: &i32 = &v[2]; println!("The third element is {third}"); let third: Option<&i32> = v.get(2); match third { Some(third) => println!("The third element is {third}"), None => println!("There is no third element."), } }
Перебор значений в вектора
fn main() { let v = vec![100, 32, 57]; for i in &v { println!("{i}"); } }
Хранение в векторах своих типов Enum
#![allow(unused)] fn main() { enum SpreadsheetCell { Int(i32), Float(f64), Text(String), } let row = vec![ SpreadsheetCell::Int(3), SpreadsheetCell::Text(String::from("blue")), SpreadsheetCell::Float(10.12), ]; }
Хранение закодированного текста UTF-8 в строках
Строки String
В Rust есть только один строковый тип в ядре языка - срез строки
str, обычно используемый в заимствованном виде как&str.
String фактически реализован как обёртка вокруг вектора байтов с некоторыми дополнительными гарантиями, ограничениями и возможностями
#![allow(unused)] fn main() { let mut s = String::new(); }
to_string преобразует все к типажу Display
#![allow(unused)] fn main() { let data = "initial contents"; let s = data.to_string(); // The method also works on a literal directly: let s = "initial contents".to_string(); }
push_str добавляет строку
- переменная должна быть mut
- добавляет в конец строки строку
#![allow(unused)] fn main() { let mut s1 = String::from("foo"); let s2 = "bar"; s1.push_str(s2); println!("s2 is {s2}"); }
push добавляет в конец строки символ
#![allow(unused)] fn main() { let mut s = String::from("lo"); s.push('l'); }
+ и макрос format!
#![allow(unused)] fn main() { let s1 = String::from("Hello, "); let s2 = String::from("world!"); let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used }
Работает по принципу макроса println!
#![allow(unused)] fn main() { let s1 = String::from("tic"); let s2 = String::from("tac"); let s3 = String::from("toe"); let s = format!("{s1}-{s2}-{s3}"); }
Получение символов по индексу
существует три способа рассмотрения строк с точки зрения Rust: как байты, как скалярные значения и как кластеры графем
#![allow(unused)] fn main() { let hello = "Здравствуйте"; let s = &hello[0..4]; }
выведет 4 байта или 2 буквы
- Для перебора букв использовать метод
chars - Для перебора байт использовать метод
bytes
#![allow(unused)] fn main() { for c in "Зд".chars() { println!("{c}"); } З д for b in "Зд".bytes() { println!("{b}"); } 208 151 208 180 }
HashMap
Тип
HashMap<K, V>хранит ключи типаKна значения типаV. Данная структура организует и хранит данные с помощью функции хеширования.
Создание новой хеш-карты
#![allow(unused)] fn main() { use std::collections::HashMap; let mut scores = HashMap::new(); //создание новой карты scores.insert(String::from("Blue"), 10); //добавить элемент в карту scores.insert(String::from("Yellow"), 50); }
Доступ к hash по get
#![allow(unused)] fn main() { let team_name = String::from("Blue"); let score = scores.get(&team_name).copied().unwrap_or(0); }
перебор карт
#![allow(unused)] fn main() { use std::collections::HashMap; let mut scores = HashMap::new(); scores.insert(String::from("Blue"), 10); scores.insert(String::from("Yellow"), 50); for (key, value) in &scores { println!("{key}: {value}"); } }
Хэш карты забирают владение на себя. Нужно это учитывать.
Перезапись старых значений
#![allow(unused)] fn main() { use std::collections::HashMap; let mut scores = HashMap::new(); scores.insert(String::from("Blue"), 10); scores.insert(String::from("Blue"), 25); println!("{scores:?}"); }
просто перезапишет новое значение. Новое значение будет вставлено, если нет такого ключа.
Добавить только новые значения и не перезаписывать старые
#![allow(unused)] fn main() { scores.entry(String::from("Yellow")).or_insert(50); scores.entry(String::from("Blue")).or_insert(50); }
метод entry позволяет добавить только не существующие значения вместе с or_insert
Считает количество повторений
#![allow(unused)] fn main() { use std::collections::HashMap; let text = "hello world wonderful world"; let mut map = HashMap::new(); //создали hash for word in text.split_whitespace() { let count = map.entry(word).or_insert(0); // добавим новый если нет и присвоим 0 *count += 1; //разыменовали ссылку на ключ и увеличили на 1 } println!("{map:?}"); }
Хэширование
Hasher - это тип, реализующий трейт BuildHasher.
функция хеширования SipHash, может противостоять атакам класса: отказ в обслуживании, Denial of Service (DoS) с использованием хеш-таблиц siphash.