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
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> |