Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

Почему 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 стоит вашего внимания