mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-11-25 20:14:30 +03:00
332 lines
13 KiB
Markdown
332 lines
13 KiB
Markdown
---
|
||
language: Rust
|
||
contributors:
|
||
- ["P1start", "http://p1start.github.io/"]
|
||
translators:
|
||
- ["Volodymyr Korniichuk", "https://github.com/ezhikus"]
|
||
filename: learnrust-uk.rs
|
||
lang: uk-ua
|
||
---
|
||
|
||
Rust - це мова програмування, що розрабляється спільнотою Mozilla Research
|
||
Rust поєднує в собі низькорівневий контроль швидкодії з високорівневими
|
||
інструментами забезпечення гарантій цілісності та безпеки.
|
||
|
||
Rust досягає своїх цілей без автоматичного збирання сміття і не вимагає
|
||
наявності певного середовища виконання, що робить можливим пряму заміну
|
||
бібліотек, написаних на мові С на бібліотеки, написані на Rust.
|
||
|
||
Перший реліз Rust (версія 0.1) вийшла в січні 2012 року і з тих пір оновлення
|
||
виходили так часто, що загальною порадою розробникам було не чекати якоїсь
|
||
стабільної версії, а використовувати нічні збірки компілятора.
|
||
|
||
15 травня 2015 року вийшла версія Rust 1.0. Для цієї версії була дана гарантія
|
||
зворотної сумісності. Подальші нічні збірки покращили швидкість компіляції та
|
||
деякі інші аспекти. На даний момент оновлення Rust виходять кожні 6 тижнів.
|
||
Бета-версія Rust 1.1 вийшла одночасно з релізом Rust 1.0.
|
||
|
||
Не зважаючи на те, що Rust є відносно низькорівневою мовою програмування, в
|
||
ній є деякі концепти, притаманні високорівневим мовам. Це робить Rust не лише
|
||
швидким, але й досить зручним та ефективним інструментом розробки.
|
||
|
||
```rust
|
||
// Це коментар. Він починається в цьому рядку...
|
||
// і продовжується в цьому
|
||
|
||
/// Цей коментар включає в себе документацію і підтримує markdown.
|
||
/// # Приклади
|
||
///
|
||
/// ```
|
||
/// let five = 5
|
||
/// ```
|
||
|
||
///////////////
|
||
// 1. Основи //
|
||
///////////////
|
||
|
||
#[allow(dead_code)]
|
||
// Функції
|
||
// `i32` - це 32-бітний цілочислений знаковий тип даних
|
||
fn add2(x: i32, y: i32) -> i32 {
|
||
// неявне повернення результату (в кінці рядку немає крапки з комою)
|
||
x + y
|
||
}
|
||
|
||
#[allow(unused_variables)]
|
||
#[allow(unused_assignments)]
|
||
#[allow(dead_code)]
|
||
// Головна функція
|
||
fn main() {
|
||
// Числа //
|
||
|
||
// Незмінне число
|
||
let x: i32 = 1;
|
||
|
||
// суфікси для позначення цілого числа та числа з плаваючою змінною
|
||
let y: i32 = 13i32;
|
||
let f: f64 = 1.3f64;
|
||
|
||
// Вивід типів
|
||
// Як правило, Rust може самостійно визначити тип змінної, отож
|
||
// ви можете не прописувати його явно
|
||
// В даному документі типи явно прописані в багатьох місцях, це зроблено
|
||
// виключно в навчальних цілях. В реальному коді вивід типів спрацює
|
||
// в більшості випадків
|
||
let implicit_x = 1;
|
||
let implicit_f = 1.3;
|
||
|
||
// арифметика
|
||
let sum = x + y + 13;
|
||
|
||
// Змінні
|
||
let mut mutable = 1;
|
||
mutable = 4;
|
||
mutable += 2;
|
||
|
||
// Строки //
|
||
|
||
// Строкові літерали
|
||
let x: &str = "Привіт, світ!";
|
||
|
||
// Друк на екран
|
||
println!("{} {}", f, x); // 1.3 Привіт, світ!
|
||
|
||
// `String` – строка, що розміщується в "купі"
|
||
let s: String = "hello world".to_string();
|
||
|
||
// Строковий зріз - це незмінне відображення якоїсь строки (або її частини)
|
||
// Зріз можна розглядати як константну пару покажчиків (на початок та кінець
|
||
// якоїсь строки)
|
||
let s_slice: &str = &s;
|
||
|
||
println!("{} {}", s, s_slice); // Привіт, світ! Привіт, світ!
|
||
|
||
// Вектори/масиви //
|
||
|
||
// Масив фіксованого розміру
|
||
let four_ints: [i32; 4] = [1, 2, 3, 4];
|
||
|
||
// Масив змінного розміру (вектор)
|
||
let mut vector: Vec<i32> = vec![1, 2, 3, 4];
|
||
vector.push(5);
|
||
|
||
// Зріз - незмінне відображення масиву
|
||
// Це схоже на строковий зріз, але в даному випадку мова йде про вектори
|
||
let slice: &[i32] = &vector;
|
||
|
||
// Використовуйте `{:?}` щоб вивести щось в цілях відлагодження
|
||
println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
|
||
|
||
// Кортеж //
|
||
|
||
// Кортеж - це набір фіксованого розміру, що включає значення кількох типів
|
||
let x: (i32, &str, f64) = (1, "привіт", 3.4);
|
||
|
||
// розбираємо кортеж "х" на окремі змінні "a", "b" та "с"
|
||
let (a, b, c) = x;
|
||
println!("{} {} {}", a, b, c); // 1 привіт 3.4
|
||
|
||
// доступ по індексу
|
||
println!("{}", x.1); // привіт
|
||
|
||
//////////////
|
||
// 2. Типи //
|
||
//////////////
|
||
|
||
// Структура
|
||
struct Point {
|
||
x: i32,
|
||
y: i32,
|
||
}
|
||
|
||
let origin: Point = Point { x: 0, y: 0 };
|
||
|
||
// Структура з безіменними полями, "кортежна структура"
|
||
struct Point2(i32, i32);
|
||
|
||
let origin2 = Point2(0, 0);
|
||
|
||
// перелічуваний тип даних
|
||
enum Direction {
|
||
Left,
|
||
Right,
|
||
Up,
|
||
Down,
|
||
}
|
||
|
||
let up = Direction::Up;
|
||
|
||
// перелічуваний тип даних з полями
|
||
enum OptionalI32 {
|
||
AnI32(i32),
|
||
Nothing,
|
||
}
|
||
|
||
let two: OptionalI32 = OptionalI32::AnI32(2);
|
||
let nothing = OptionalI32::Nothing;
|
||
|
||
// Узагальнене програмування //
|
||
|
||
struct Foo<T> { bar: T }
|
||
|
||
// Ось так стандартна бібліотека Rust оголошує `Option`
|
||
enum Optional<T> {
|
||
SomeVal(T),
|
||
NoVal,
|
||
}
|
||
|
||
// Методи //
|
||
|
||
impl<T> Foo<T> {
|
||
// Методи приймають неявний параметр `self`
|
||
fn get_bar(self) -> T {
|
||
self.bar
|
||
}
|
||
}
|
||
|
||
let a_foo = Foo { bar: 1 };
|
||
println!("{}", a_foo.get_bar()); // 1
|
||
|
||
// Типажі (в інших мовах програмування схожою сутністю є інтерфейси) //
|
||
|
||
trait Frobnicate<T> {
|
||
fn frobnicate(self) -> Option<T>;
|
||
}
|
||
|
||
impl<T> Frobnicate<T> for Foo<T> {
|
||
fn frobnicate(self) -> Option<T> {
|
||
Some(self.bar)
|
||
}
|
||
}
|
||
|
||
let another_foo = Foo { bar: 1 };
|
||
println!("{:?}", another_foo.frobnicate()); // Some(1)
|
||
|
||
/////////////////////////
|
||
// 3. Відповідність шаблону //
|
||
/////////////////////////
|
||
|
||
let foo = OptionalI32::AnI32(1);
|
||
match foo {
|
||
OptionalI32::AnI32(n) => println!("Це тип i32: {}", n),
|
||
OptionalI32::Nothing => println!("Це ніщо!"),
|
||
}
|
||
|
||
// Складніший приклад
|
||
struct FooBar { x: i32, y: OptionalI32 }
|
||
let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
|
||
|
||
match bar {
|
||
FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
|
||
println!("Числа рівні нулю!"),
|
||
FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
|
||
println!("Числа однакові"),
|
||
FooBar { x: n, y: OptionalI32::AnI32(m) } =>
|
||
println!("Числа різні: {} {}", n, m),
|
||
FooBar { x: _, y: OptionalI32::Nothing } =>
|
||
println!("Друге число - ніщо!"),
|
||
}
|
||
|
||
/////////////////////
|
||
// 4. Потік керування //
|
||
/////////////////////
|
||
|
||
// Цикл `for`
|
||
let array = [1, 2, 3];
|
||
for i in array {
|
||
println!("{}", i);
|
||
}
|
||
|
||
// Діапазони
|
||
for i in 0u32..10 {
|
||
print!("{} ", i);
|
||
}
|
||
println!("");
|
||
// друкує `0 1 2 3 4 5 6 7 8 9 `
|
||
|
||
// `if`
|
||
if 1 == 1 {
|
||
println!("Математика працює!");
|
||
} else {
|
||
println!("Ой, лишенько...");
|
||
}
|
||
|
||
// `if` як вираз
|
||
let value = if true {
|
||
"добре"
|
||
} else {
|
||
"погано"
|
||
};
|
||
|
||
// Цикл `while`
|
||
while 1 == 1 {
|
||
println!("Всесвіт функціонує стабільно.");
|
||
// Вираз break перериває цикл
|
||
break
|
||
}
|
||
|
||
// Нескінченний цикл
|
||
loop {
|
||
println!("Привіт!");
|
||
// Вираз break перериває цикл
|
||
break
|
||
}
|
||
|
||
/////////////////////////////////
|
||
// 5. Вказівники і безпека пам'яті //
|
||
/////////////////////////////////
|
||
|
||
// Володіючий вказівник - тільки хтось один може "володіти" вказівником в
|
||
// будь-який момент. Це означає, що коли "Box" вийде за межі області
|
||
// видимості - його можна безпечно звільнити
|
||
let mut mine: Box<i32> = Box::new(3);
|
||
*mine = 5; // розіменування `mine` з присвоєнням йому нового значення
|
||
// `now_its_mine` перебирає на себе володіння над `mine`. Іншими словами,
|
||
// `mine` переміщується.
|
||
let mut now_its_mine = mine;
|
||
*now_its_mine += 2;
|
||
|
||
println!("{}", now_its_mine); // 7
|
||
// println!("{}", mine); // цей код не скомпілюється, оскільки тепер
|
||
// покажчиком на дані володіє `now_its_mine`
|
||
|
||
// Посилання – незмінний вказівник на дані
|
||
// При створенні посилання на якесь значення, ми говоримо, що значення
|
||
// було "запозичене". Поки значення є запозиченим - воно не може бути
|
||
// змінене або переміщене. Запозичення пропадає, як тільки стається вихід з
|
||
// області видимості, де було створене посилання
|
||
let mut var = 4;
|
||
var = 3;
|
||
let ref_var: &i32 = &var;
|
||
|
||
println!("{}", var); // На відміну від `mine`, `var` можна використати
|
||
println!("{}", *ref_var);
|
||
// var = 5; // цей код не скомпілюється, оскільки `var` зараз є запозиченим
|
||
// *ref_var = 6; // цей код також не зкомпілюється, оскільки `ref_var`
|
||
// є незмінним посиланням
|
||
|
||
// Змінне посилання
|
||
// Значення можна запозичити з можливістю зміни. У цьому випадку доступ до
|
||
// оригінального значення втрачається.
|
||
let mut var2 = 4;
|
||
let ref_var2: &mut i32 = &mut var2;
|
||
*ref_var2 += 2; // '*' використовується для доступу до змінного посилання
|
||
|
||
println!("{}", *ref_var2); // 6 , // при заміні на var2 код не зкомпілюється
|
||
// ref_var2 має тип &mut i32, отож зберігає посилання на i32, а не значення
|
||
// var2 = 2; // цей рядок не зкомпілюється, оскільки `var2` є запозиченим.
|
||
}
|
||
```
|
||
|
||
## Матеріали для самовдосконалення
|
||
|
||
В даному матеріалі ми оглянули лише основи Rust. Більше матеріалу ви можете
|
||
знайти на сайті
|
||
[The Rust Programming Language](http://doc.rust-lang.org/book/index.html)
|
||
Також існує Reddit-розділ [/r/rust](http://reddit.com/r/rust). Люди на каналі
|
||
irc.mozilla.org також завжди раді допомогти новачкам.
|
||
|
||
Ви можете спробувати можливості Rust за допомогою онлайн-компілятора на сторінці
|
||
[Rust Playground](https://play.rust-lang.org) або
|
||
[Rust website](http://rust-lang.org).
|