Здравей, Rust
Въведение
04 октомври 2018
Административни неща
- Сайт на курса (може би временен): https://fmi.rust-lang.bg/
Административни неща
- Сайт на курса (може би временен): https://fmi.rust-lang.bg/
- Лекции: https://fmi.rust-lang.bg/lectures
Административни неща
- Сайт на курса (може би временен): https://fmi.rust-lang.bg/
- Лекции: https://fmi.rust-lang.bg/lectures
- Discord: https://discord.gg/FCTNfbZ
Hello, world!
Защото винаги от там се почва:
fn main() {
println!("Hello, world!");
}
Компилация
Можем да използваме компилатора на Rust - rustc
Компилация
Можем да използваме компилатора на Rust - rustc
$ rustc hello.rs
$ ./hello
Hello, world!
Компилация
Но, разбира се, има по-лесен начин
Компилация
Но, разбира се, има по-лесен начин
$ cargo new hello
$ cargo run
Hello, world!
Cargo
Cargo
- Package manager
Cargo
- Package manager
- Task runner
Cargo
- Package manager
- Task runner
- Подобно на
mix
в elixir,bundler
в ruby,npm
в node.js
Инсталация
Инсталация
Инсталация
Инсталация
- https://2017.fmi.rust-lang.bg/topics/1
- Rustup (https://rustup.rs/)
$ rustup install stable
Инсталация
- https://2017.fmi.rust-lang.bg/topics/1
- Rustup (https://rustup.rs/)
$ rustup install stable
$ rustup doc
The Rust Book
Rust playpen
Променливи
Променливи се декларират с let
let NAME = VALUE;
let NAME: TYPE = VALUE;
Типът може се пропусне, ако е ясен от контекста.
let x = 5;
let y: i32 = 3;
Променливи
shadowing
let x = 10;
let x = x + 10;
let x = x * 3;
// ...
Променливи
shadowing
let x1 = 10;
let x2 = x1 + 10;
let x3 = x2 * 3;
// ...
Променливи
shadowing
let x = 10;
{
let x = x + 10;
{
let x = x * 3;
// ...
}
}
Променливи
mutability
Променливите са immutable по подразбиране
let x = 5;
x += 1;
Променливи
mutability
Променливите са immutable по подразбиране
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
let mut x = 5;
x += 1;
Основни типове
Целочислени типове
Основни типове
Целочислени типове
i8
,i16
,i32
,i64
,i128
,isize
u8
,u16
,u32
,u64
,u128
,usize
Основни типове
Целочислени типове
i8
,i16
,i32
,i64
,i128
,isize
u8
,u16
,u32
,u64
,u128
,usize
iN
- цяло (signed) число с размер N бита
Основни типове
Целочислени типове
i8
,i16
,i32
,i64
,i128
,isize
u8
,u16
,u32
,u64
,u128
,usize
iN
- цяло (signed) число с размер N битаuN
- неотрицателно (unsigned) число с размер N бита
Основни типове
Целочислени типове
i8
,i16
,i32
,i64
,i128
,isize
u8
,u16
,u32
,u64
,u128
,usize
iN
- цяло (signed) число с размер N битаuN
- неотрицателно (unsigned) число с размер N битаisize
иusize
имат размер колкото машинната дума - 32 бита на 32 битов ОС и 64 бита на 64 битов ОС
Основни типове
Целочислени типове (литерали)
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
- Големи числа:
133_587
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
- Големи числа:
133_587
42_u32
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
- Големи числа:
133_587
42_u32
1_0_0_0
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
- Големи числа:
133_587
42_u32
1_0_0_0
1_____________________________________________________4
Основни типове
Целочислени типове (в различни бройни системи)
Основни типове
Целочислени типове (в различни бройни системи)
- Hex:
0xDEADBEEF
Основни типове
Целочислени типове (в различни бройни системи)
- Hex:
0xDEADBEEF
- Octal:
0o77
Основни типове
Целочислени типове (в различни бройни системи)
- Hex:
0xDEADBEEF
- Octal:
0o77
- Binary:
0b1010011010
Основни типове
Числа с плаваща запетая
Основни типове
Числа с плаваща запетая
f32
f64
Основни типове
Числа с плаваща запетая
f32
f64
- съответно 32 битов и 64 битов float
Основни типове
bool
Основни типове
bool
bool
Основни типове
bool
bool
- стойности
true
иfalse
Основни типове
unit
Основни типове
unit
()
Основни типове
unit
()
- тип с големина 0 байта (zero sized type)
- тип без стойност (но не в смисъла на
null
) - подобно на
void
в C/C++, но по-полезно - използва се при generics
Основни типове
unit
()
- тип с големина 0 байта (zero sized type)
- тип без стойност (но не в смисъла на
null
) - подобно на
void
в C/C++, но по-полезно - използва се при generics
let x: () = ();
Основни типове
Низове
Основни типове
Низове
str
Основни типове
Низове
str
- utf8 низ
- ще му обърнем повече внимание в бъдеща лекция.
Основни типове
Низове
str
- utf8 низ
- ще му обърнем повече внимание в бъдеща лекция.
let s: &str = "Rust рулит!!!";
Основни типове
Символи
Основни типове
Символи
char
Основни типове
Символи
char
- unicode code point
- различно е от
u8
- ще му обърнем внимание заедно с низовете
Основни типове
Символи
char
- unicode code point
- различно е от
u8
- ще му обърнем внимание заедно с низовете
let love: char = '❤';
Основни типове
Масиви
[T; n]
let arr: [i32; 3] = [1, 2, 3];
let nested: [[i32; 3]; 2] = [
[1, 2, 3],
[4, 5, 6],
];
Основни типове
Кортежи (tuples)
(A, B, C, ...)
let tuple: (i32, u32, bool) = (1, 2, false);
let unit: () = ();
Основни типове
Сравнение със C
Length | Rust | C/C++ | ||
---|---|---|---|---|
Signed | Unsigned | Signed | Unsigned | |
8-bit | i8 | u8 | char | unsigned char |
16-bit | i16 | u16 | short | unsigned short |
32-bit | i32 | u32 | int | unsigned int |
64-bit | i64 | u64 | long long | unsigned long long |
word | isize | usize | long | unsigned long / size_t |
Length | Rust | C/C++ |
---|---|---|
32-bit | f32 | float |
64-bit | f64 | double |
Rust | C/C++ |
---|---|
bool | bool |
() | void |
Специфики
Няма автоматично конвертиране между различни числови типове
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
Специфики
Аритметични операции не могат да се прилагат върху различни типове
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
let one = true as u8;
let two_hundred = -56_i8 as u8;
let three = 3.14 as u32;
Специфики
В режим debug, аритметични операции хвърлят грешка при препълванe (integer overflow / underflow)
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.
Специфики
Няма оператори ++
и --
x += 1;
x -= 1;
Коментари
Едноредов коментар
// 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 поддържа и блокови коментари
/*
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-клауза
if bool_expression {
// ...
} else if another_bool_expression {
// ...
} else {
// ...
}
Забележете, че няма скоби около условието и скобите за блок { }
са задължителни.
Control flow
Цикли
for
цикъла работи с итератори, за които ще говорим в бъдеща лекция
for var in iterator {
// ...
}
Отново няма скоби след for
и скобите за блок { }
са задължителни.
Control flow
Цикли
Също така има и while
и loop
цикли.
loop
e същото като while true
, но по-четимо.
while bool_expression {
// ...
}
loop {
// ...
}
Функции
fn main() {
println!("Hello, world!");
another_function();
}
fn another_function() {
println!("Another function.");
}
Hello, world! Another function.
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
- Задаването на типове на параметрите и резултата е задължително (няма type inference)
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
- Задаването на типове на параметрите и резултата е задължително (няма type inference)
- Върнатата стойност е стойността на последния израз в тялото на функцията
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
- Задаването на типове на параметрите и резултата е задължително (няма type inference)
- Върнатата стойност е стойността на последния израз в тялото на функцията
- Ако искаме да излезем от функцията преди последния ред, може да използваме
return
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
- Задаването на типове на параметрите и резултата е задължително (няма type inference)
- Върнатата стойност е стойността на последния израз в тялото на функцията
- Ако искаме да излезем от функцията преди последния ред, може да използваме
return
- Използване на
return
на последния ред от тялото се счита за лоша практика
Statements & Expressions
Израз (expression)
Statements & Expressions
Израз (expression)
- операция, която връща резултат
Statements & Expressions
Израз (expression)
- операция, която връща резултат
1
Statements & Expressions
Израз (expression)
- операция, която връща резултат
1
(2 + 3) * 4
Statements & Expressions
Израз (expression)
- операция, която връща резултат
1
(2 + 3) * 4
add(5, 6)
Statements & Expressions
Твърдение (statement)
Statements & Expressions
Твърдение (statement)
- инструкция, която извършва някакво действие и няма резултат
Statements & Expressions
Твърдение (statement)
- инструкция, която извършва някакво действие и няма резултат
let x = 10;
Statements & Expressions
Твърдение (statement)
- инструкция, която извършва някакво действие и няма резултат
let x = 10;
return 25;
Statements & Expressions
Твърдение (statement)
- инструкция, която извършва някакво действие и няма резултат
let x = 10;
return 25;
fn add(a: i32, b: i32) { a + b }
Statements & Expressions
Твърдение (statement)
- инструкция, която извършва някакво действие и няма резултат
let x = 10;
return 25;
fn add(a: i32, b: i32) { a + b }
- ако добавим
;
след израз го превръщаме в твърдение
Statements & Expressions
Твърдение (statement)
Пример: можем да присвояваме стойността на израз на променлива с let
, но не и стойността на твърдение (защото няма стойност)
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
Много от констукциите на езика са изрази.
Блоковете са израз - стойността им е стойността на последния израз в блока
fn main() {
let x = {
let a = 1;
let b = 2;
a + b
};
println!("x = {}", x);
}
x = 3
Statements & Expressions
if-else конструкцията е израз
let bigger = if a > b {
a
} else {
b
};
Rust няма тернарен оператор по тази причина
let bigger = if a > b { a } else { b };
Statements & Expressions
loop
е израз
let x = loop {
break 5;
};
Macros
Macros
- служат за генериране на код
Macros
- служат за генериране на код
- различават се от функциите по
!
след името
Macros
- служат за генериране на код
- различават се от функциите по
!
след името println!
Macros
- служат за генериране на код
- различават се от функциите по
!
след името println!
print!
println! macro
let x = 5;
let y = 10;
println!("x = {} and y = {}", x, y);
x = 5 and y = 10
println! macro
let x = 5;
let y = 10;
println!("x = {} and y = {}", x, y);
x = 5 and y = 10
- Принтиране на конзолата
println! macro
let x = 5;
let y = 10;
println!("x = {} and y = {}", x, y);
x = 5 and y = 10
- Принтиране на конзолата
{}
placeholders