SlideShare a Scribd company logo
Почему Rust стоит вашего внимания
Панков Михаил
14 мая 2015 г.
Панков Михаил Почему Rust стоит вашего внимания
Что такое Rust
Безопасность работы с памятью
Безопасные: Java, C#, Python, Ruby
Опасные: C, C++
Среда исполнения и эффективность
Байт-код, большая среда и сборщик мусора: Java, C#, ...
Машинный код, маленькая среда, ручное управление
памятью: C, C++
Rust
Безопасный, при этом компилируется в машинный код
Проще встраивать
Проще профилировать
Статически гарантирует безопасность работы с памятью
Панков Михаил Почему Rust стоит вашего внимания
Что такое Rust (продолжение)
Rust — системный язык программирования, который быстро
работает, предотвращает почти все падения, и устраняет гонки
по данным.
Панков Михаил Почему Rust стоит вашего внимания
Hello World
1 fn main() {
2 println!("Привет, мир!");
3 }
Панков Михаил Почему Rust стоит вашего внимания
Детсадовский калькулятор
1 fn main() {
2 let program = "+ + * - /";
3 let mut accumulator = 0;
4 for token in program.chars() {
5 match token {
6 ’+’ => accumulator += 1,
7 ’-’ => accumulator -= 1,
8 ’*’ => accumulator *= 2,
9 ’/’ => accumulator /= 2,
10 _ => { /* игнорируем всё остальное */ }
11 }
12 }
13 println!("Программа "{}" вычислила значение {}",
14 program, accumulator);
15 }
Панков Михаил Почему Rust стоит вашего внимания
Перемещение по умолчанию
1 let v = vec![1, 2, 3];
2
3 let v2 = v;
4
5 println!("v[0] is: {}", v[0]);
error: use of moved value: ‘v‘
println!("v[0] is: {}", v[0]);
^
Панков Михаил Почему Rust стоит вашего внимания
Перемещение по умолчанию (продолжение)
1 fn take(v: Vec<i32>) {
2 // что здесь происходит - неважно
3 }
4
5 let v = vec![1, 2, 3];
6
7 take(v);
8
9 println!("v[0] is: {}", v[0]);
error: use of moved value: ‘v‘
println!("v[0] is: {}", v[0]);
^
Панков Михаил Почему Rust стоит вашего внимания
Как использовать освобождённую память
1 void * allocate_new_buffer(size_t number)
2 {
3 return malloc(number * sizeof (int));
4 }
5 int main(int argc, char *argv[])
6 {
7 int *numbers = allocate_new_buffer(10);
8 for (int i = 0; i < 10; ++ i) {
9 numbers[i] = i;
10 }
11 // ...
12 free(numbers);
13 // ...
14 }
Панков Михаил Почему Rust стоит вашего внимания
Как использовать освобождённую память (продолжение)
1 void * allocate_new_buffer(size_t number); //...
2 int main(int argc, char *argv[])
3 {
4 int *numbers = allocate_new_buffer(10);
5 for (int i = 0; i < 10; ++ i) {
6 numbers[i] = i;
7 }
8 // ...
9 free(numbers);
10 // ...
11 for (int i = 0; i < 10; ++ i) {
12 printf("%d ", numbers[i]);
13 }
14 }
Панков Михаил Почему Rust стоит вашего внимания
Как обратиться к освобождённой памяти в Rust
1 fn allocate_new_buffer(number: usize) -> Vec<isize> {
2 return Vec::with_capacity(number);
3 }
4 fn main() {
5 let mut numbers = allocate_new_buffer(10);
6 numbers.extend(0..10);
7 // ...
8 drop(numbers);
9 // ...
10 println!("{:?}", numbers);
11 // ^^^^^^^
12 // error: use of moved value
13 }
Панков Михаил Почему Rust стоит вашего внимания
Идиоматичный код на Rust
1 fn main() {
2 let numbers: Vec<_> = (0..10).collect();
3 // ...
4 println!("{:?}", numbers);
5 // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
6 // неявный вызов drop(numbers)
7 }
Панков Михаил Почему Rust стоит вашего внимания
Заимствование
1 fn main() {
2 let mut x = 42;
3 let y = &mut x;
4 *y = 43;
5 x = 44;
6 }
5:11 error: cannot assign to ‘x‘ because it is borrowed
x = 44;
^~~~~~
3:19 note: borrow of ‘x‘ occurs here
let y = &mut x;
^
error: aborting due to previous error
Панков Михаил Почему Rust стоит вашего внимания
Изменяемость
1 void process(std::string input)
2 {
3 for (auto i = input.begin(); i != input.end(); ++ i) {
4 if (*i == ’o’) {
5 input.push_back(’z’);
6 }
7 }
8 std::cout << input;
9 }
10 int main(int argc, char *argv[])
11 {
12 auto string = "Hello world";
13 process(string);
14 return 0;
15 }
Панков Михаил Почему Rust стоит вашего внимания
Изменяемость в Rust
1 fn process(input: String) {
2 for c in input.chars() {
3 if c == ’o’ {
4 input.push(’z’);
5 // ^^
6 // Cannot borrow immutable local variable
7 // as mutable
8 }
9 }
10 }
11
12 fn main() {
13 let string = "Hello world".to_string();
14 process(string);
15 }
Панков Михаил Почему Rust стоит вашего внимания
Изменяемость в Rust (продолжение)
1 fn process(mut input: String) {
2 for c in input.chars() {
3 // ^^^^^
4 // previous borrow occurs here
5 if c == ’o’ {
6 input.push(’z’);
7 // ^^
8 // Cannot borrow ‘input‘ as mutable
9 // because it’s also borrowed as immutable
10 }
11 }
12 }
13 fn main() {
14 let string = "Hello world".to_string();
15 process(string);
16 }
Панков Михаил Почему Rust стоит вашего внимания
Время жизни
1 struct Foo<’a> {
2 x: &’a i32,
3 }
4 fn main() {
5 let x; // -+ x оживает
6 // |
7 { // |
8 let y = &5; // ---+ y оживает
9 let f = Foo { x: y }; // ---+ f оживает
10 x = &f.x; // | | здесь ошибка
11 } // ---+ f и y умирают
12 // |
13 println!("{}", x); // |
14 } // -+ x умирает
Панков Михаил Почему Rust стоит вашего внимания
Обобщённое программирование. Типажи
1 struct Circle {
2 x: f64,
3 y: f64,
4 radius: f64,
5 }
6 trait HasArea {
7 fn area(&self) -> f64;
8 }
9 impl HasArea for Circle {
10 fn area(&self) -> f64 {
11 std::f64::consts::PI * (self.radius * self.radius)
12 }
13 }
Панков Михаил Почему Rust стоит вашего внимания
Обобщённое программирование. Ограничения
1 fn print_area<T>(shape: T) {
2 println!("Площадь фигуры: {}", shape.area());
3 }
4 // error: type ‘T‘ does not implement any method in scope
5 // named ‘area‘
6
7 fn print_area<T: HasArea>(shape: T) {
8 println!("Площадь фигуры: {}", shape.area());
9 }
10 // ok
Панков Михаил Почему Rust стоит вашего внимания
RAII в Rust
1 pub struct Fd {
2 raw_fd: c95_t::c_int,
3 }
4 impl Fd {
5 pub fn open(path: &str) -> Result<Fd, i32> {
6 let c_path = CString::new(path).unwrap();
7 let fd = unsafe {
8 posix88_f::fcntl::open(c_path.as_ptr(),
9 posix88_c::O_RDONLY, 0)
10 } as i32;
11 if fd > -1000 && fd < 0 {
12 return Err(-fd);
13 }
14 Ok(Fd { raw_fd: fd })
15 }
Панков Михаил Почему Rust стоит вашего внимания
RAII в Rust (продолжение)
1 pub fn raw(&self) -> c95_t::c_int {
2 self.raw_fd
3 }
4 pub fn get_size(&self) -> Result<i64, i32> {
5 // ...
6 Ok(file_info.st_size)
7 }
8 }
9 impl Drop for Fd {
10 fn drop(&mut self) {
11 unsafe {
12 posix88_f::unistd::close(self.raw_fd);
13 }
14 }
15 }
Панков Михаил Почему Rust стоит вашего внимания
RAII в Rust (использование)
1 fn read_print_file(path: &str) -> Result<(), ()> {
2 let maybe_fd = fd::Fd::open(path);
3 let fd: fd::Fd;
4 match maybe_fd {
5 Ok(f) => fd = f,
6 Err(errno) => {
7 print_error(
8 &format!("Couldn’t open file: {}", c_helpers
9 return Err(());
10 }
11 }
12 let mut remaining_file_size = fd.get_size().unwrap();
Панков Михаил Почему Rust стоит вашего внимания
Обрабатываем ошибки идиоматично
1 fn read_print_file(path: &str) -> Result<(), ()> {
2 let maybe_fd = fd::Fd::open(path);
3 let fd = match maybe_fd {
4 Ok(f) => f,
5 Err(errno) => {
6 print_error(
7 &format!("Couldn’t open file: {}", c_helpers
8 return Err(());
9 }
10 }
11 let mut remaining_file_size = fd.get_size().unwrap();
Панков Михаил Почему Rust стоит вашего внимания
Ложь и бенчмарки
$ ls -l /boot/memtest86+.elf
-rw-r--r-- 1 root root 178176 марта 12 2014 /boot/memtest86
$ time hd /boot/memtest86+.elf
...
hd /boot/memtest86+.elf 0,11s user 0,06s system
8% cpu 1,929 total
$ time hexdump/hexdump /boot/memtest86+.elf
...
hexdump/hexdump /boot/memtest86+.elf 0,06s user 0,07s syste
6% cpu 2,031 total
$ time rexdump/rexdump /boot/memtest86+.elf
...
./rexdump /boot/memtest86+.elf 0,14s user 0,07s system
10% cpu 2,056 total
$
Панков Михаил Почему Rust стоит вашего внимания
Ложь и бенчмарки (продолжение)
C — BSD C — моя Rust — моя
0
0.2
0.4
0.6
0.8
1
0.9
относительноебыстродействие
Панков Михаил Почему Rust стоит вашего внимания
Как устроить гонку по данным
1 THREADS = 10
2 COUNT = 50
3 $x = 1
4 THREADS.times.map { |t|
5 Thread.new {
6 COUNT.times { |c|
7 a = $x + 1
8 sleep 0.001
9 puts "Thread #{t} wrote #{a}"
10 $x = a
11 }
12 }
13 }.each(&:join)
14 puts "Got $x = #{$x}."
Панков Михаил Почему Rust стоит вашего внимания
Потокобезопасный код на Rust: попытка 0
1 fn main() {
2 let threads = 10;
3 let count = 50;
4 let mut x = 1;
5 for _ in 0..threads {
6 std::thread::spawn(|| {
7 for _ in 0..count {
8 let a = x + 1; // error: closure borrows x
9 std::thread::sleep_ms(1);
10 x = a;
11 }
12 });
13 }
14 println!("The result is {}", x);
15 }
Панков Михаил Почему Rust стоит вашего внимания
Что говорит компилятор
data-race.rs:6:28: 12:10 error: closure may outlive the
current function, but it borrows ‘x‘,
which is owned by the current function [E0373]
data-race.rs:6 std::thread::spawn(|| {
data-race.rs:7 for _ in 0..count {
data-race.rs:8 let a = x + 1;
data-race.rs:9 std::thread::sleep_ms(1);
data-race.rs:10 x = a;
data-race.rs:11 }
...
data-race.rs:8:25: 8:26 note: ‘x‘ is borrowed here
data-race.rs:8 let a = x + 1;
^
Панков Михаил Почему Rust стоит вашего внимания
Потокобезопасный код на Rust: попытка 1
1 fn main() {
2 let threads = 10;
3 let count = 50;
4 let mut x = 1;
5 for _ in 0..threads {
6 thread::scoped(|| { // warning: thread will be
7 for _ in 0..count { // immideately joined
8 let a = x + 1;
9 thread::sleep_ms(1);
10 x = a;
11 }
12 });
13 }
14 println!("The result is {}", x);
15 }
Панков Михаил Почему Rust стоит вашего внимания
Потокобезопасный код на Rust: попытка 2
1 // ...
2 let mut guards: Vec<JoinGuard<()>> = Vec::new();
3 for _ in 0..threads {
4 let g: JoinGuard<()> =
5 thread::scoped(|| {
6 for _ in 0..count {
7 let a = x + 1; // error: cannot borrow ‘x‘
8 thread::sleep_ms(1); // mutably borrowed
9 x = a;
10 }
11 });
12 guards.push(g);
13 }
14 drop(guards);
15 println!("The result is {}", x);
Панков Михаил Почему Rust стоит вашего внимания
Рабочий потокобезопасный код на Rust
1 fn main() {
2 let threads = 10;
3 let count = 50;
4 let x = &AtomicUsize::new(1);
5 let _: Vec<_> = (0..threads).map(|_| {
6 thread::scoped(move || {
7 for _ in 0..count {
8 thread::sleep_ms(1);
9 x.fetch_add(1, Ordering::SeqCst);
10 }
11 })
12 }).collect();
13 println!("The result is {}", x.load(Ordering::SeqCst));
14 }
Панков Михаил Почему Rust стоит вашего внимания
Тестирование
1 #[test]
2 fn it_works() {
3 assert_eq!(4, add_two(2));
4 }
$ cargo test
Compiling adder v0.0.1 (file:///home/you/projects/adder)
Running target/adder-91b3e234d4ed382a
running 1 test
test it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
Doc-tests adder
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
Панков Михаил Почему Rust стоит вашего внимания
Бенчмарки
1 #[bench]
2 fn bench_add_two(b: &mut Bencher) {
3 b.iter(|| add_two(2));
4 }
$ cargo bench
Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
Running target/release/adder-91b3e234d4ed382a
running 2 tests
test tests::it_works ... ignored
test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)
test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
Панков Михаил Почему Rust стоит вашего внимания
Стабильность
master: A - B - C - .... - G - H - I - J - K
  
beta:   . - K’
 
stable:  . - I’ - J’ - K’
 | |
1.0.0: . - E’ - G’ | |
| | |
1.0.1: . - I’ | |
| |
1.1.0: . |
|
1.1.1: .
Панков Михаил Почему Rust стоит вашего внимания
Инструменты
Автодополнение с Racer
Навигация по коду: rusty-tags
Проверка кода в реальном времени: flycheck-rust, syntastic
Панков Михаил Почему Rust стоит вашего внимания
Инфраструктура
Crates.io — 2000 контейнеров
Разработка языка на GitHub
Изменения через RFC из основной команды или
сообщества
Панков Михаил Почему Rust стоит вашего внимания
Cargo
Сборка
Зависимости
Crates.io
git
Cargo.lock
cargo update
Документация
Тесты, бенчмарки
Заливка на Crates.io
cargo publish
Панков Михаил Почему Rust стоит вашего внимания
IDE — RustDT
https://github.com/RustDT/RustDT
Поддерка Cargo
Автодополнение и поиск определений
Отладка
Панков Михаил Почему Rust стоит вашего внимания
RustDT. Редактор
Панков Михаил Почему Rust стоит вашего внимания
RustDT. Автодополнение
Панков Михаил Почему Rust стоит вашего внимания
RustDT. Отладка
Панков Михаил Почему Rust стоит вашего внимания
Кто уже использует Rust
Servo
400 тысяч строк кода
4-х поточная версия отрисовывает Reddit в 5 раз быстрее
Gecko (55 против 250 миллисекунд)
Piston
hematite — клон Minecraft
Iron
84 тысячи запросов в секунду для простейшего сервера
Панков Михаил Почему Rust стоит вашего внимания
84 тысячи запросов в секунду
http://www.yesodweb.com/blog/2011/03/
preliminary-warp-cross-language-benchmarks
Панков Михаил Почему Rust стоит вашего внимания
Кто уже использует Rust (продолжение)
OpenDNS
Skylight
MaidSafe
Панков Михаил Почему Rust стоит вашего внимания
Ресурсы
Книга «Язык программирования Rust»
https://github.com/kgv/rust_book_ru
IRC канал на русском
http://client00.chat.mibbit.com/?server=irc.
mozilla.org&channel=%23rust-ru
Русский StackOverflow — тег Rust
http://ru.stackoverflow.com/questions/tagged/rust
Лента событий на Timepad
https://rust-v-moskve.timepad.ru/
Веб-интерфейс к компилятору
http://play.rust-lang.org/
Домашняя страница со ссылками на англоязычные
ресурсы
http://www.rust-lang.org
Панков Михаил Почему Rust стоит вашего внимания
Где найти этот доклад
http://michaelpankov.com/why-rust-matters.pdf
Панков Михаил Почему Rust стоит вашего внимания

More Related Content

PDF
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
PDF
Fabric для управления серверами
PDF
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
PDF
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
PPTX
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
PDF
Парсим CSS
PDF
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
PDF
Использование Tarantool для хранения чатов и лент друзей (Константин Осипов)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
Fabric для управления серверами
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
Парсим CSS
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Использование Tarantool для хранения чатов и лент друзей (Константин Осипов)

What's hot (20)

PDF
20130429 dynamic c_c++_program_analysis-alexey_samsonov
PDF
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
PDF
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
PDF
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
PDF
Caching data outside Java Heap and using Shared Memory in Java
PDF
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
PDF
Reform: путь к лучшему ORM
PDF
"Модифицируй это!" или "Больше магии Python с помощью изменения AST"
PDF
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
PDF
Haskell
PPT
Web осень 2012 лекция 3
PDF
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
PPTX
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...
PPT
Web весна 2013 лекция 3
PDF
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
PDF
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
PDF
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
PDF
Parallel STL
PDF
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
PDF
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
20130429 dynamic c_c++_program_analysis-alexey_samsonov
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
Caching data outside Java Heap and using Shared Memory in Java
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Reform: путь к лучшему ORM
"Модифицируй это!" или "Больше магии Python с помощью изменения AST"
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Haskell
Web осень 2012 лекция 3
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...
Web весна 2013 лекция 3
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
Parallel STL
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
Ad

Viewers also liked (10)

PDF
Практика разработки веб-серверов на Rust
PDF
Rust: история языка и контекст применения
PDF
Rust All Hands Winter 2011
PDF
Основы программирования на ruby
PDF
Вторая лекция по основам ruby для студентов itc73.ru
PDF
An introduction to Rust: the modern programming language to develop safe and ...
PDF
Лекция #5. Введение в язык программирования Python 3
KEY
Ruby basics
PDF
Rust Workshop - NITC FOSSMEET 2017
Практика разработки веб-серверов на Rust
Rust: история языка и контекст применения
Rust All Hands Winter 2011
Основы программирования на ruby
Вторая лекция по основам ruby для студентов itc73.ru
An introduction to Rust: the modern programming language to develop safe and ...
Лекция #5. Введение в язык программирования Python 3
Ruby basics
Rust Workshop - NITC FOSSMEET 2017
Ad

Similar to Почему Rust стоит вашего внимания (20)

PDF
Статический анализ: ошибки в медиаплеере и безглючная аська
PPT
CUDA Course 2010 at MSU
PDF
Про асинхронное сетевое программирование
PDF
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
PPT
2009 10-31 есть ли жизнь после mpi
PDF
Android: Как написать приложение, которое не тормозит
PPTX
DSLs in Lisp and Clojure
PDF
Лекция 6. Стандарт OpenMP
PPT
Root Conf2009 Fin
PDF
Александр Крижановский, NatSys Lab
PDF
Лекция 8. Intel Threading Building Blocks
PDF
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
PDF
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
PDF
Леонид Васильев "Python в инфраструктуре поиска"
PDF
static - defcon russia 20
PPTX
Оптимизация трассирования с использованием Expression templates
PPTX
Оптимизация трассирования с использованием Expression templates
PDF
Что нового в Perl 5.14
PDF
Сладкое будущее: Phalcon и Zephir
Статический анализ: ошибки в медиаплеере и безглючная аська
CUDA Course 2010 at MSU
Про асинхронное сетевое программирование
Объектно-Ориентированное Программирование на C++, Лекции 1 и 2
2009 10-31 есть ли жизнь после mpi
Android: Как написать приложение, которое не тормозит
DSLs in Lisp and Clojure
Лекция 6. Стандарт OpenMP
Root Conf2009 Fin
Александр Крижановский, NatSys Lab
Лекция 8. Intel Threading Building Blocks
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Леонид Васильев "Python в инфраструктуре поиска"
static - defcon russia 20
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
Что нового в Perl 5.14
Сладкое будущее: Phalcon и Zephir

Почему Rust стоит вашего внимания

  • 1. Почему Rust стоит вашего внимания Панков Михаил 14 мая 2015 г. Панков Михаил Почему Rust стоит вашего внимания
  • 2. Что такое Rust Безопасность работы с памятью Безопасные: Java, C#, Python, Ruby Опасные: C, C++ Среда исполнения и эффективность Байт-код, большая среда и сборщик мусора: Java, C#, ... Машинный код, маленькая среда, ручное управление памятью: C, C++ Rust Безопасный, при этом компилируется в машинный код Проще встраивать Проще профилировать Статически гарантирует безопасность работы с памятью Панков Михаил Почему Rust стоит вашего внимания
  • 3. Что такое Rust (продолжение) Rust — системный язык программирования, который быстро работает, предотвращает почти все падения, и устраняет гонки по данным. Панков Михаил Почему Rust стоит вашего внимания
  • 4. Hello World 1 fn main() { 2 println!("Привет, мир!"); 3 } Панков Михаил Почему Rust стоит вашего внимания
  • 5. Детсадовский калькулятор 1 fn main() { 2 let program = "+ + * - /"; 3 let mut accumulator = 0; 4 for token in program.chars() { 5 match token { 6 ’+’ => accumulator += 1, 7 ’-’ => accumulator -= 1, 8 ’*’ => accumulator *= 2, 9 ’/’ => accumulator /= 2, 10 _ => { /* игнорируем всё остальное */ } 11 } 12 } 13 println!("Программа "{}" вычислила значение {}", 14 program, accumulator); 15 } Панков Михаил Почему Rust стоит вашего внимания
  • 6. Перемещение по умолчанию 1 let v = vec![1, 2, 3]; 2 3 let v2 = v; 4 5 println!("v[0] is: {}", v[0]); error: use of moved value: ‘v‘ println!("v[0] is: {}", v[0]); ^ Панков Михаил Почему Rust стоит вашего внимания
  • 7. Перемещение по умолчанию (продолжение) 1 fn take(v: Vec<i32>) { 2 // что здесь происходит - неважно 3 } 4 5 let v = vec![1, 2, 3]; 6 7 take(v); 8 9 println!("v[0] is: {}", v[0]); error: use of moved value: ‘v‘ println!("v[0] is: {}", v[0]); ^ Панков Михаил Почему Rust стоит вашего внимания
  • 8. Как использовать освобождённую память 1 void * allocate_new_buffer(size_t number) 2 { 3 return malloc(number * sizeof (int)); 4 } 5 int main(int argc, char *argv[]) 6 { 7 int *numbers = allocate_new_buffer(10); 8 for (int i = 0; i < 10; ++ i) { 9 numbers[i] = i; 10 } 11 // ... 12 free(numbers); 13 // ... 14 } Панков Михаил Почему Rust стоит вашего внимания
  • 9. Как использовать освобождённую память (продолжение) 1 void * allocate_new_buffer(size_t number); //... 2 int main(int argc, char *argv[]) 3 { 4 int *numbers = allocate_new_buffer(10); 5 for (int i = 0; i < 10; ++ i) { 6 numbers[i] = i; 7 } 8 // ... 9 free(numbers); 10 // ... 11 for (int i = 0; i < 10; ++ i) { 12 printf("%d ", numbers[i]); 13 } 14 } Панков Михаил Почему Rust стоит вашего внимания
  • 10. Как обратиться к освобождённой памяти в Rust 1 fn allocate_new_buffer(number: usize) -> Vec<isize> { 2 return Vec::with_capacity(number); 3 } 4 fn main() { 5 let mut numbers = allocate_new_buffer(10); 6 numbers.extend(0..10); 7 // ... 8 drop(numbers); 9 // ... 10 println!("{:?}", numbers); 11 // ^^^^^^^ 12 // error: use of moved value 13 } Панков Михаил Почему Rust стоит вашего внимания
  • 11. Идиоматичный код на Rust 1 fn main() { 2 let numbers: Vec<_> = (0..10).collect(); 3 // ... 4 println!("{:?}", numbers); 5 // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 6 // неявный вызов drop(numbers) 7 } Панков Михаил Почему Rust стоит вашего внимания
  • 12. Заимствование 1 fn main() { 2 let mut x = 42; 3 let y = &mut x; 4 *y = 43; 5 x = 44; 6 } 5:11 error: cannot assign to ‘x‘ because it is borrowed x = 44; ^~~~~~ 3:19 note: borrow of ‘x‘ occurs here let y = &mut x; ^ error: aborting due to previous error Панков Михаил Почему Rust стоит вашего внимания
  • 13. Изменяемость 1 void process(std::string input) 2 { 3 for (auto i = input.begin(); i != input.end(); ++ i) { 4 if (*i == ’o’) { 5 input.push_back(’z’); 6 } 7 } 8 std::cout << input; 9 } 10 int main(int argc, char *argv[]) 11 { 12 auto string = "Hello world"; 13 process(string); 14 return 0; 15 } Панков Михаил Почему Rust стоит вашего внимания
  • 14. Изменяемость в Rust 1 fn process(input: String) { 2 for c in input.chars() { 3 if c == ’o’ { 4 input.push(’z’); 5 // ^^ 6 // Cannot borrow immutable local variable 7 // as mutable 8 } 9 } 10 } 11 12 fn main() { 13 let string = "Hello world".to_string(); 14 process(string); 15 } Панков Михаил Почему Rust стоит вашего внимания
  • 15. Изменяемость в Rust (продолжение) 1 fn process(mut input: String) { 2 for c in input.chars() { 3 // ^^^^^ 4 // previous borrow occurs here 5 if c == ’o’ { 6 input.push(’z’); 7 // ^^ 8 // Cannot borrow ‘input‘ as mutable 9 // because it’s also borrowed as immutable 10 } 11 } 12 } 13 fn main() { 14 let string = "Hello world".to_string(); 15 process(string); 16 } Панков Михаил Почему Rust стоит вашего внимания
  • 16. Время жизни 1 struct Foo<’a> { 2 x: &’a i32, 3 } 4 fn main() { 5 let x; // -+ x оживает 6 // | 7 { // | 8 let y = &5; // ---+ y оживает 9 let f = Foo { x: y }; // ---+ f оживает 10 x = &f.x; // | | здесь ошибка 11 } // ---+ f и y умирают 12 // | 13 println!("{}", x); // | 14 } // -+ x умирает Панков Михаил Почему Rust стоит вашего внимания
  • 17. Обобщённое программирование. Типажи 1 struct Circle { 2 x: f64, 3 y: f64, 4 radius: f64, 5 } 6 trait HasArea { 7 fn area(&self) -> f64; 8 } 9 impl HasArea for Circle { 10 fn area(&self) -> f64 { 11 std::f64::consts::PI * (self.radius * self.radius) 12 } 13 } Панков Михаил Почему Rust стоит вашего внимания
  • 18. Обобщённое программирование. Ограничения 1 fn print_area<T>(shape: T) { 2 println!("Площадь фигуры: {}", shape.area()); 3 } 4 // error: type ‘T‘ does not implement any method in scope 5 // named ‘area‘ 6 7 fn print_area<T: HasArea>(shape: T) { 8 println!("Площадь фигуры: {}", shape.area()); 9 } 10 // ok Панков Михаил Почему Rust стоит вашего внимания
  • 19. RAII в Rust 1 pub struct Fd { 2 raw_fd: c95_t::c_int, 3 } 4 impl Fd { 5 pub fn open(path: &str) -> Result<Fd, i32> { 6 let c_path = CString::new(path).unwrap(); 7 let fd = unsafe { 8 posix88_f::fcntl::open(c_path.as_ptr(), 9 posix88_c::O_RDONLY, 0) 10 } as i32; 11 if fd > -1000 && fd < 0 { 12 return Err(-fd); 13 } 14 Ok(Fd { raw_fd: fd }) 15 } Панков Михаил Почему Rust стоит вашего внимания
  • 20. RAII в Rust (продолжение) 1 pub fn raw(&self) -> c95_t::c_int { 2 self.raw_fd 3 } 4 pub fn get_size(&self) -> Result<i64, i32> { 5 // ... 6 Ok(file_info.st_size) 7 } 8 } 9 impl Drop for Fd { 10 fn drop(&mut self) { 11 unsafe { 12 posix88_f::unistd::close(self.raw_fd); 13 } 14 } 15 } Панков Михаил Почему Rust стоит вашего внимания
  • 21. RAII в Rust (использование) 1 fn read_print_file(path: &str) -> Result<(), ()> { 2 let maybe_fd = fd::Fd::open(path); 3 let fd: fd::Fd; 4 match maybe_fd { 5 Ok(f) => fd = f, 6 Err(errno) => { 7 print_error( 8 &format!("Couldn’t open file: {}", c_helpers 9 return Err(()); 10 } 11 } 12 let mut remaining_file_size = fd.get_size().unwrap(); Панков Михаил Почему Rust стоит вашего внимания
  • 22. Обрабатываем ошибки идиоматично 1 fn read_print_file(path: &str) -> Result<(), ()> { 2 let maybe_fd = fd::Fd::open(path); 3 let fd = match maybe_fd { 4 Ok(f) => f, 5 Err(errno) => { 6 print_error( 7 &format!("Couldn’t open file: {}", c_helpers 8 return Err(()); 9 } 10 } 11 let mut remaining_file_size = fd.get_size().unwrap(); Панков Михаил Почему Rust стоит вашего внимания
  • 23. Ложь и бенчмарки $ ls -l /boot/memtest86+.elf -rw-r--r-- 1 root root 178176 марта 12 2014 /boot/memtest86 $ time hd /boot/memtest86+.elf ... hd /boot/memtest86+.elf 0,11s user 0,06s system 8% cpu 1,929 total $ time hexdump/hexdump /boot/memtest86+.elf ... hexdump/hexdump /boot/memtest86+.elf 0,06s user 0,07s syste 6% cpu 2,031 total $ time rexdump/rexdump /boot/memtest86+.elf ... ./rexdump /boot/memtest86+.elf 0,14s user 0,07s system 10% cpu 2,056 total $ Панков Михаил Почему Rust стоит вашего внимания
  • 24. Ложь и бенчмарки (продолжение) C — BSD C — моя Rust — моя 0 0.2 0.4 0.6 0.8 1 0.9 относительноебыстродействие Панков Михаил Почему Rust стоит вашего внимания
  • 25. Как устроить гонку по данным 1 THREADS = 10 2 COUNT = 50 3 $x = 1 4 THREADS.times.map { |t| 5 Thread.new { 6 COUNT.times { |c| 7 a = $x + 1 8 sleep 0.001 9 puts "Thread #{t} wrote #{a}" 10 $x = a 11 } 12 } 13 }.each(&:join) 14 puts "Got $x = #{$x}." Панков Михаил Почему Rust стоит вашего внимания
  • 26. Потокобезопасный код на Rust: попытка 0 1 fn main() { 2 let threads = 10; 3 let count = 50; 4 let mut x = 1; 5 for _ in 0..threads { 6 std::thread::spawn(|| { 7 for _ in 0..count { 8 let a = x + 1; // error: closure borrows x 9 std::thread::sleep_ms(1); 10 x = a; 11 } 12 }); 13 } 14 println!("The result is {}", x); 15 } Панков Михаил Почему Rust стоит вашего внимания
  • 27. Что говорит компилятор data-race.rs:6:28: 12:10 error: closure may outlive the current function, but it borrows ‘x‘, which is owned by the current function [E0373] data-race.rs:6 std::thread::spawn(|| { data-race.rs:7 for _ in 0..count { data-race.rs:8 let a = x + 1; data-race.rs:9 std::thread::sleep_ms(1); data-race.rs:10 x = a; data-race.rs:11 } ... data-race.rs:8:25: 8:26 note: ‘x‘ is borrowed here data-race.rs:8 let a = x + 1; ^ Панков Михаил Почему Rust стоит вашего внимания
  • 28. Потокобезопасный код на Rust: попытка 1 1 fn main() { 2 let threads = 10; 3 let count = 50; 4 let mut x = 1; 5 for _ in 0..threads { 6 thread::scoped(|| { // warning: thread will be 7 for _ in 0..count { // immideately joined 8 let a = x + 1; 9 thread::sleep_ms(1); 10 x = a; 11 } 12 }); 13 } 14 println!("The result is {}", x); 15 } Панков Михаил Почему Rust стоит вашего внимания
  • 29. Потокобезопасный код на Rust: попытка 2 1 // ... 2 let mut guards: Vec<JoinGuard<()>> = Vec::new(); 3 for _ in 0..threads { 4 let g: JoinGuard<()> = 5 thread::scoped(|| { 6 for _ in 0..count { 7 let a = x + 1; // error: cannot borrow ‘x‘ 8 thread::sleep_ms(1); // mutably borrowed 9 x = a; 10 } 11 }); 12 guards.push(g); 13 } 14 drop(guards); 15 println!("The result is {}", x); Панков Михаил Почему Rust стоит вашего внимания
  • 30. Рабочий потокобезопасный код на Rust 1 fn main() { 2 let threads = 10; 3 let count = 50; 4 let x = &AtomicUsize::new(1); 5 let _: Vec<_> = (0..threads).map(|_| { 6 thread::scoped(move || { 7 for _ in 0..count { 8 thread::sleep_ms(1); 9 x.fetch_add(1, Ordering::SeqCst); 10 } 11 }) 12 }).collect(); 13 println!("The result is {}", x.load(Ordering::SeqCst)); 14 } Панков Михаил Почему Rust стоит вашего внимания
  • 31. Тестирование 1 #[test] 2 fn it_works() { 3 assert_eq!(4, add_two(2)); 4 } $ cargo test Compiling adder v0.0.1 (file:///home/you/projects/adder) Running target/adder-91b3e234d4ed382a running 1 test test it_works ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Doc-tests adder running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured Панков Михаил Почему Rust стоит вашего внимания
  • 32. Бенчмарки 1 #[bench] 2 fn bench_add_two(b: &mut Bencher) { 3 b.iter(|| add_two(2)); 4 } $ cargo bench Compiling adder v0.0.1 (file:///home/steve/tmp/adder) Running target/release/adder-91b3e234d4ed382a running 2 tests test tests::it_works ... ignored test tests::bench_add_two ... bench: 1 ns/iter (+/- 0) test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured Панков Михаил Почему Rust стоит вашего внимания
  • 33. Стабильность master: A - B - C - .... - G - H - I - J - K beta: . - K’ stable: . - I’ - J’ - K’ | | 1.0.0: . - E’ - G’ | | | | | 1.0.1: . - I’ | | | | 1.1.0: . | | 1.1.1: . Панков Михаил Почему Rust стоит вашего внимания
  • 34. Инструменты Автодополнение с Racer Навигация по коду: rusty-tags Проверка кода в реальном времени: flycheck-rust, syntastic Панков Михаил Почему Rust стоит вашего внимания
  • 35. Инфраструктура Crates.io — 2000 контейнеров Разработка языка на GitHub Изменения через RFC из основной команды или сообщества Панков Михаил Почему Rust стоит вашего внимания
  • 36. Cargo Сборка Зависимости Crates.io git Cargo.lock cargo update Документация Тесты, бенчмарки Заливка на Crates.io cargo publish Панков Михаил Почему Rust стоит вашего внимания
  • 37. IDE — RustDT https://github.com/RustDT/RustDT Поддерка Cargo Автодополнение и поиск определений Отладка Панков Михаил Почему Rust стоит вашего внимания
  • 38. RustDT. Редактор Панков Михаил Почему Rust стоит вашего внимания
  • 39. RustDT. Автодополнение Панков Михаил Почему Rust стоит вашего внимания
  • 40. RustDT. Отладка Панков Михаил Почему Rust стоит вашего внимания
  • 41. Кто уже использует Rust Servo 400 тысяч строк кода 4-х поточная версия отрисовывает Reddit в 5 раз быстрее Gecko (55 против 250 миллисекунд) Piston hematite — клон Minecraft Iron 84 тысячи запросов в секунду для простейшего сервера Панков Михаил Почему Rust стоит вашего внимания
  • 42. 84 тысячи запросов в секунду http://www.yesodweb.com/blog/2011/03/ preliminary-warp-cross-language-benchmarks Панков Михаил Почему Rust стоит вашего внимания
  • 43. Кто уже использует Rust (продолжение) OpenDNS Skylight MaidSafe Панков Михаил Почему Rust стоит вашего внимания
  • 44. Ресурсы Книга «Язык программирования Rust» https://github.com/kgv/rust_book_ru IRC канал на русском http://client00.chat.mibbit.com/?server=irc. mozilla.org&channel=%23rust-ru Русский StackOverflow — тег Rust http://ru.stackoverflow.com/questions/tagged/rust Лента событий на Timepad https://rust-v-moskve.timepad.ru/ Веб-интерфейс к компилятору http://play.rust-lang.org/ Домашняя страница со ссылками на англоязычные ресурсы http://www.rust-lang.org Панков Михаил Почему Rust стоит вашего внимания
  • 45. Где найти этот доклад http://michaelpankov.com/why-rust-matters.pdf Панков Михаил Почему Rust стоит вашего внимания