+++ title = "Расттест 1" date = "2022-08-18" [taxonomies] tags = ["rust"] +++ ### Какой тип имеет переменная `result`? ```rust fn count_uppercase(s: &str) -> usize { let result = { let upper = s.chars().filter(|c| c.is_uppercase()).collect::(); return upper.len(); }; } ```
Ответ `result` имеет тип `!` (never type/никогдатый тип). В `result` записывается результат выполнения блока инструкций в фигурных скобочках. Блок `{ ... }` всегда возвращает значение, но как быть, если мы натыкаемся на `return`, прерывающий поток выполнения программы и возвращающий значение из **функции**, а не из блока? Для этого в раст завезли служебный тип `!`, показывающий, что тип данной переменной никогда не будет присвоен. Если бы мы переписали функцию следующим образом: ```rust fn count_uppercase(s: &str) -> usize { let result = { let upper = s.chars().filter(|c| c.is_uppercase()).collect::(); upper.len() }; return result } ``` то `result` бы имел верный тип `usize`. [Почитать ещё](https://doc.rust-lang.org/book/ch19-04-advanced-types.html#the-never-type-that-never-returns) P.S.: обычно в расте принято опускать `return` и писать вместо него возвращаемое значение без `;`. Это трактуется как возврат значения из текущего блока (в том числе функции)

### Ограничен ли дженерик-тип `T` какими-либо трейтами? ```rust pub fn drop(_x: T) { } ```
Ответ Да, по умолчанию любые дженерики имеют ограничение `T: Sized`. Этот трейт реализован для всех типов, размер которых известен на момент компиляции. Для отмены ограничения используется следующий синтаксис: ```rust pub fn drop(_x: T) { } ``` означающий, что функция может принимать безразмерные типы (DST), такие как `dyn Trait`, `[u8]`, `str` и т.д.

### Есть ли отличия между следующими кусками кода? ```rust const GLOBAL_MUTEX: Mutex = Mutex::new(0); ``` и ```rust static GLOBAL_MUTEX: Mutex = Mutex::new(0); ```
Ответ `const` клонирует значение константы во все места её использования. В результате вместо изменения глобального мьютекса мы получаем несколько клонированных мьютексов и часы дебага. В случае со `static` программа действительно создаёт один глобальный мьютекс, который можно изменять из разных потоков. Это известная проблема, о которой не сигнализирует `rustc`, поэтому будет полезно дополнительно использовать `clippy` в вашем проекте. Он не только отловит неверное использование констант, но привьёт вам чувство прекрасного растового кода. [Почитать ещё](https://rust-lang.github.io/rust-clippy/master/index.html#/declare_interior_mutable_const)