https://ortem.xyz website source code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

88 lines
4.0 KiB

+++
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::<String>();
return upper.len();
};
}
```
<details><summary>Ответ</summary>
`result` имеет тип `!` (never type/никогдатый тип).
В `result` записывается результат выполнения блока инструкций в фигурных скобочках.
Блок `{ ... }` всегда возвращает значение, но как быть, если мы натыкаемся на `return`,
прерывающий поток выполнения программы и возвращающий значение из **функции**, а не из блока?
Для этого в раст завезли служебный тип `!`, показывающий, что тип данной переменной никогда не будет присвоен.
Если бы мы переписали функцию следующим образом:
```rust
fn count_uppercase(s: &str) -> usize {
let result = {
let upper = s.chars().filter(|c| c.is_uppercase()).collect::<String>();
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` и писать вместо него возвращаемое значение без `;`.
Это трактуется как возврат значения из текущего блока (в том числе функции)
</details>
<br>
### Ограничен ли дженерик-тип `T` какими-либо трейтами?
```rust
pub fn drop<T>(_x: T) { }
```
<details><summary>Ответ</summary>
Да, по умолчанию любые дженерики имеют ограничение `T: Sized`.
Этот трейт реализован для всех типов, размер которых известен на момент компиляции.
Для отмены ограничения используется следующий синтаксис:
```rust
pub fn drop<T: ?Sized>(_x: T) { }
```
означающий, что функция может принимать безразмерные типы (DST), такие как `dyn Trait`, `[u8]`, `str` и т.д.
</details>
<br>
### Есть ли отличия между следующими кусками кода?
```rust
const GLOBAL_MUTEX: Mutex<i32> = Mutex::new(0);
```
и
```rust
static GLOBAL_MUTEX: Mutex<i32> = Mutex::new(0);
```
<details><summary>Ответ</summary>
`const` клонирует значение константы во все места её использования.
В результате вместо изменения глобального мьютекса мы получаем несколько клонированных мьютексов и часы дебага.
В случае со `static` программа действительно создаёт один глобальный мьютекс, который можно изменять из разных потоков.
Это известная проблема, о которой не сигнализирует `rustc`,
поэтому будет полезно дополнительно использовать `clippy` в вашем проекте. Он не только отловит неверное использование констант,
но привьёт вам чувство прекрасного растового кода.
[Почитать ещё](https://rust-lang.github.io/rust-clippy/master/index.html#/declare_interior_mutable_const)
</details>
<br>