rust.md

Личный сайт Go-разработчика из Казани

Язык 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. Множество ресурсов на разных языках можно найти в этом проекте.