Здравей, Rust

Въведение

04 октомври 2018

Административни неща

Административни неща

Административни неща

Hello, world!

Защото винаги от там се почва:

1 2 3
fn main() {
    println!("Hello, world!");
}

Компилация

Можем да използваме компилатора на Rust - rustc

Компилация

Можем да използваме компилатора на Rust - rustc

1 2 3
$ rustc hello.rs
$ ./hello
Hello, world!

Компилация

Но, разбира се, има по-лесен начин

Компилация

Но, разбира се, има по-лесен начин

1 2 3
$ cargo new hello
$ cargo run
Hello, world!

Cargo

Cargo

Cargo

Cargo

Инсталация

Инсталация

Инсталация

Инсталация

Инсталация

The Rust Book

https://doc.rust-lang.org/book/2018-edition/

Rust playpen

https://play.rust-lang.org/

Променливи

Променливи се декларират с let

let NAME = VALUE;
let NAME: TYPE = VALUE;

Типът може се пропусне, ако е ясен от контекста.

1 2
let x = 5;
let y: i32 = 3;

Променливи

shadowing

1 2 3 4
let x = 10;
let x = x + 10;
let x = x * 3;
// ...

Променливи

shadowing

1 2 3 4
let x1 = 10;
let x2 = x1 + 10;
let x3 = x2 * 3;
// ...

Променливи

shadowing

1 2 3 4 5 6 7 8 9 10
let x = 10;

{
    let x = x + 10;

    {
        let x = x * 3;
        // ...
    }
}

Променливи

mutability

Променливите са immutable по подразбиране

1 2
let x = 5;
x += 1;

Променливи

mutability

Променливите са immutable по подразбиране

1 2
let x = 5;
x += 1;
error[E0384]: cannot assign twice to immutable variable `x`
 --> /src/main_5.rs:6:1
  |
5 | let x = 5;
  |     - first assignment to `x`
6 | x += 1;
  | ^^^^^^ cannot assign twice to immutable variable

Променливи

mutability

За да се направи mutable се използва ключовата дума mut

1 2
let mut x = 5;
x += 1;

Основни типове

Целочислени типове

Основни типове

Целочислени типове

Основни типове

Целочислени типове

Основни типове

Целочислени типове

Основни типове

Целочислени типове

Основни типове

Целочислени типове (литерали)

Основни типове

Целочислени типове (литерали)

Основни типове

Целочислени типове (литерали)

Основни типове

Целочислени типове (литерали)

Основни типове

Целочислени типове (литерали)

Основни типове

Целочислени типове (литерали)

Основни типове

Целочислени типове (литерали)

Основни типове

Целочислени типове (в различни бройни системи)

Основни типове

Целочислени типове (в различни бройни системи)

Основни типове

Целочислени типове (в различни бройни системи)

Основни типове

Целочислени типове (в различни бройни системи)

Основни типове

Числа с плаваща запетая

Основни типове

Числа с плаваща запетая

Основни типове

Числа с плаваща запетая

Основни типове

bool

Основни типове

bool

Основни типове

bool

Основни типове

unit

Основни типове

unit

Основни типове

unit

Основни типове

unit

1
let x: () = ();

Основни типове

Низове

Основни типове

Низове

Основни типове

Низове

Основни типове

Низове

1
let s: &str = "Rust рулит!!!";

Основни типове

Символи

Основни типове

Символи

Основни типове

Символи

Основни типове

Символи

1
let love: char = '❤';

Основни типове

Масиви

1 2 3 4 5 6
let arr: [i32; 3] = [1, 2, 3];

let nested: [[i32; 3]; 2] = [
    [1, 2, 3],
    [4, 5, 6],
];

Основни типове

Кортежи (tuples)

1 2
let tuple: (i32, u32, bool) = (1, 2, false);
let unit: () = ();

Основни типове

Сравнение със C

LengthRustC/C++
SignedUnsignedSignedUnsigned
8-biti8u8charunsigned char
16-biti16u16shortunsigned short
32-biti32u32intunsigned int
64-biti64u64long longunsigned long long
wordisizeusizelongunsigned long / size_t
Length Rust C/C++
32-bit f32 float
64-bit f64 double
Rust C/C++
bool bool
() void

Специфики

Няма автоматично конвертиране между различни числови типове

1 2
let x: i32 = 1;
let y: u64 = x;
error[E0308]: mismatched types
 --> /src/main_11.rs:5:14
  |
5 | let y: u64 = x;
  |              ^ expected u64, found i32

Специфики

Аритметични операции не могат да се прилагат върху различни типове

1 2
let x = 4_u32 - 1_u8;
let y = 1.2_f64 / 0.8_f32;
error[E0308]: mismatched types
 --> /src/main_12.rs:4:17
  |
4 | let x = 4_u32 - 1_u8;
  |                 ^^^^ expected u32, found u8

error[E0277]: cannot subtract `u8` from `u32`
 --> /src/main_12.rs:4:15
  |
4 | let x = 4_u32 - 1_u8;
  |               ^ no implementation for `u32 - u8`
  |
  = help: the trait `std::ops::Sub<u8>` is not implemented for `u32`

error[E0308]: mismatched types
 --> /src/main_12.rs:5:19
  |
5 | let y = 1.2_f64 / 0.8_f32;
  |                   ^^^^^^^ expected f64, found f32

error[E0277]: cannot divide `f64` by `f32`
 --> /src/main_12.rs:5:17
  |
5 | let y = 1.2_f64 / 0.8_f32;
  |                 ^ no implementation for `f64 / f32`
  |
  = help: the trait `std::ops::Div<f32>` is not implemented for `f64`

Специфики

За конвертиране между типове се използва ключовата дума as

1 2 3
let one = true as u8;
let two_hundred = -56_i8 as u8;
let three = 3.14 as u32;

Специфики

В режим debug, аритметични операции хвърлят грешка при препълванe (integer overflow / underflow)

1 2 3
let x = 255_u8;
let y = x + 1;                // 💥
println!("{}", y);
thread 'main' panicked at 'attempt to add with overflow', /src/main_14.rs:4:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Специфики

Няма оператори ++ и --

1 2
x += 1;
x -= 1;

Коментари

Едноредов коментар

1 2 3
// So we’re doing something complicated here, long enough that we need
// multiple lines of comments to do it! Whew! Hopefully, this comment will
// explain what’s going on.

Rust поддържа и блокови коментари

1 2 3 4 5
/*
So we’re doing something complicated here, long enough that we need
multiple lines of comments to do it! Whew! Hopefully, this comment will
explain what’s going on.
*/

Control flow

if-клаузи

Синтаксис на if-клауза

1 2 3 4 5 6 7
if bool_expression {
    // ...
} else if another_bool_expression {
    // ...
} else {
    // ...
}

Забележете, че няма скоби около условието и скобите за блок { } са задължителни.

Control flow

Цикли

for цикъла работи с итератори, за които ще говорим в бъдеща лекция

1 2 3
for var in iterator {
    // ...
}

Отново няма скоби след for и скобите за блок { } са задължителни.

Control flow

Цикли

Също така има и while и loop цикли.

loop e същото като while true, но по-четимо.

1 2 3
while bool_expression {
    // ...
}

1 2 3
loop {
    // ...
}

Функции

1 2 3 4 5 6 7 8
fn main() {
    println!("Hello, world!");
    another_function();
}

fn another_function() {
    println!("Another function.");
}
Hello, world!
Another function.

Функции

1 2 3 4
fn add(a: u32, b: u32) -> u32 {
    // note no semicolon
    a + b
}

Функции

1 2 3 4
fn add(a: u32, b: u32) -> u32 {
    // note no semicolon
    a + b
}

Функции

1 2 3 4
fn add(a: u32, b: u32) -> u32 {
    // note no semicolon
    a + b
}

Функции

1 2 3 4
fn add(a: u32, b: u32) -> u32 {
    // note no semicolon
    a + b
}

Функции

1 2 3 4
fn add(a: u32, b: u32) -> u32 {
    // note no semicolon
    a + b
}

Statements & Expressions

Израз (expression)

Statements & Expressions

Израз (expression)

Statements & Expressions

Израз (expression)

Statements & Expressions

Израз (expression)

Statements & Expressions

Израз (expression)

Statements & Expressions

Твърдение (statement)

Statements & Expressions

Твърдение (statement)

Statements & Expressions

Твърдение (statement)

Statements & Expressions

Твърдение (statement)

Statements & Expressions

Твърдение (statement)

Statements & Expressions

Твърдение (statement)

Statements & Expressions

Твърдение (statement)

Пример: можем да присвояваме стойността на израз на променлива с let, но не и стойността на твърдение (защото няма стойност)

1
let x = (let y = 10);
error: expected expression, found statement (`let`)
 --> /src/main_21.rs:3:10
  |
3 | let x = (let y = 10);
  |          ^^^ expected expression
  |
  = note: variable declaration using `let` is a statement

Statements & Expressions

Много от констукциите на езика са изрази.

Блоковете са израз - стойността им е стойността на последния израз в блока

1 2 3 4 5 6 7 8 9
fn main() {
    let x = {
        let a = 1;
        let b = 2;
        a + b
    };

    println!("x = {}", x);
}
x = 3

Statements & Expressions

if-else конструкцията е израз

1 2 3 4 5
let bigger = if a > b {
    a
} else {
    b
};

Rust няма тернарен оператор по тази причина

1
let bigger = if a > b { a } else { b };

Statements & Expressions

loop е израз

1 2 3
let x = loop {
    break 5;
};

Macros

Macros

Macros

Macros

Macros

println! macro

1 2 3
let x = 5;
let y = 10;
println!("x = {} and y = {}", x, y);
x = 5 and y = 10

println! macro

1 2 3
let x = 5;
let y = 10;
println!("x = {} and y = {}", x, y);
x = 5 and y = 10

println! macro

1 2 3
let x = 5;
let y = 10;
println!("x = {} and y = {}", x, y);
x = 5 and y = 10

Въпроси