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