1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
|
---
language: rust
filename: learnrust-ru.rs
contributors:
- ["P1start", "http://p1start.github.io/"]
translators:
- ["Anatolii Kosorukov", "https://github.com/java1cprog"]
- ["Vasily Starostin", "https://github.com/Basil22"]
lang: ru-ru
---
Язык Rust разработан в Mozilla Research. Он сочетает низкоуровневую производительность с удобством языка высокого уровня и одновременно гарантирует безопасность памяти.
Он достигает этих целей без сборщика мусора или сложной среды выполнения, что позволяет использовать библиотеки Rust как прямую замену
C-библиотек. И наоборот, Rust умеет использовать готовые С-библиотеки как есть, без накладных расходов.
Первый выпуск Rust, 0.1, произошел в январе 2012 года. В течение 3 лет развитие продвигалось настолько быстро, что язык серьезно менялся без сохранения совместимости. Это дало возможность обкатать и отполировать синтаксис и возможности языка.
15 мая 2015 года был выпущен Rust 1.0 с полной гарантией обратной совместимости. Сборка поставляется в трех вариантах: стабильная версия, бета-версия, ночная версия. Все нововведения языка сперва обкатываются на ночной и бета-версиях, и только потом попадают в стабильную. Выход очередной версии происходит раз в 6 недель. В 2018 году вышло второе большое обновление языка, добавившее ему новых возможностей.
Хотя Rust является языком относительно низкого уровня, он имеет все возможности высокоуровневых языков: процедурное, объектное, функциональное, шаблонное и другие виды программирования. На данный момент Rust является одним из самых мощных (а может быть и самым) по возможностям среди статически типизированных языков. Это делает Rust не только быстрым, но и простым и эффективным для разработки сложного кода.
```rust
// Это однострочный комментарий
//
/// Так выглядит комментарий для документации
/// # Examples
///
/// ```
/// let seven = 7
/// ```
///////////////
// 1. Основы //
///////////////
// Функции
// `i32` это целочисленный знаковый тип 32-bit
#[allow(dead_code)]
fn add2(x: i32, y: i32) -> i32 {
// метод возвращает сумму x и y
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 = "hello world!";
// Печать на консоль
println!("{} {}", f, x); // 1.3 hello world
// `String` – изменяемая строка
let s: String = "hello world".to_string();
// Строковый срез - неизменяемое представление части строки
// Представляет собой пару из указателя на начало фрагмента и его длины
let s_slice: &str = &s;
println!("{} {}", s, s_slice); // hello world hello world
// Vectors/arrays //
// фиксированный массив
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, "hello", 3.4);
// Инициализация группы переменных `let`
let (a, b, c) = x;
println!("{} {} {}", a, b, c); // 1 hello 3.4
// Доступ по индексу
println!("{}", x.1); // hello
//////////////
// 2. Типы //
//////////////
// Структура
struct Point {
x: i32,
y: i32,
}
let origin: Point = Point { x: 0, y: 0 };
// Структуры могут быть с безымянными полями ‘tuple struct’
struct Point2(i32, i32);
let origin2 = Point2(0, 0);
// Перечисление
enum Direction {
Left,
Right,
Up,
Down,
}
let up = Direction::Up;
// Перечисление с полями
// В отличие от C и C++ компилятор автоматически следит за тем,
// какой именно тип хранится в перечислении.
enum OptionalI32 {
AnI32(i32),
Nothing,
}
let two: OptionalI32 = OptionalI32::AnI32(2);
let nothing = OptionalI32::Nothing;
// Обобщенные типы данных //
struct Foo<T> { bar: T }
// Частоиспользуемое перечисление стандартной библиотеки `Option`
enum Optional<T> {
SomeVal(T),
NoVal,
}
// Методы //
impl<T> Foo<T> {
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!("it’s an i32: {}", n),
OptionalI32::Nothing => println!("it’s nothing!"),
}
// Более сложный пример
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!("The numbers are zero!"),
FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
println!("The numbers are the same"),
FooBar { x: n, y: OptionalI32::AnI32(m) } =>
println!("Different numbers: {} {}", n, m),
FooBar { x: _, y: OptionalI32::Nothing } =>
println!("The second number is Nothing!"),
}
//////////////////////////////////////////////
// 4. Управление ходом выполнения программы //
//////////////////////////////////////////////
// `for` loops/iteration
let array = [1, 2, 3];
for i in array {
println!("{}", i);
}
// Диапазоны
for i in 0u32..10 {
print!("{} ", i);
}
println!("");
// prints `0 1 2 3 4 5 6 7 8 9 `
// `if`
if 1 == 1 {
println!("Maths is working!");
} else {
println!("Oh no...");
}
// `if` as expression
let value = if true {
"good"
} else {
"bad"
};
// `while` loop
while 1 == 1 {
println!("The universe is operating normally.");
break;
}
// Infinite loop
loop {
println!("Hello!");
break;
}
//////////////////////////////////
// 5. Защита памяти и указатели //
//////////////////////////////////
// Владеющий указатель – такой указатель может быть только один
// Это значит, что при выходе из блока переменная автоматически становится недействительной.
let mut mine: Box<i32> = Box::new(3);
*mine = 5; // dereference
// Здесь, `now_its_mine` получает во владение `mine`. Т.е. `mine` была перемещена.
let mut now_its_mine = mine;
*now_its_mine += 2;
println!("{}", now_its_mine); // 7
// println!("{}", mine);
// Ссылки - это неизменяемые указатели
// Если ссылка получает значения, то говорят, что она заимствует это значение.
// Такое значение не может быть изменено или перемещено.
let mut var = 4;
var = 3;
let ref_var: &i32 = &var;
println!("{}", var);
println!("{}", *ref_var);
// var = 5; // не скомпилируется
// *ref_var = 6; // и это
// Изменяемые ссылки
//
let mut var2 = 4;
let ref_var2: &mut i32 = &mut var2;
*ref_var2 += 2; // '*' используется для изменения значения
println!("{}", *ref_var2); // 6 , // var2 would not compile.
// ref_var2 имеет тип &mut i32, т.е. он содержит ссылку на i32, а не значение.
// var2 = 2; // не скомпилируется, т.к. эта переменная уже была заимствована ранее
}
```
## Более подробная информация о языке
Уже есть хорошие книги для изучающих Rust. Основным источником остаётся
[The Rust Programming Language](http://doc.rust-lang.org/book/index.html)
Для компиляции программ при изучении языка весьма удобно использовать
[Rust playpen](http://play.rust-lang.org).
Множество ресурсов на разных языках можно найти в [этом проекте](https://github.com/ctjhoa/rust-learning).
|