Здравей, Rust
Въведение
8 октомври 2024
Административни неща
- Запишете се в сайта: https://fmi.rust-lang.bg/
Hello, world!
Защото винаги от там се почва:
fn main() {
println!("Hello, world!");
}
fn main() {
println!("Hello, world!");
}
Компилация
Можем да използваме компилатора на Rust - rustc
Компилация
Можем да използваме компилатора на Rust - rustc
$ rustc hello.rs
$ ./hello
Hello, world!
Компилация
Но, разбира се, има по-лесен начин
Компилация
Но, разбира се, има по-лесен начин
$ cargo new hello
$ cd hello
$ cargo run
Hello, world!
Cargo
Cargo
- Package manager
Cargo
- Package manager
- Task runner
Cargo
- Package manager
- Task runner
- Подобно на
mixв elixir,bundlerв ruby,npm/yarnв node.js
Инсталация
Инсталация
- Rustup (https://rustup.rs/)
Инсталация
- Rustup (https://rustup.rs/)
$ rustup install stable
Инсталация
- Rustup (https://rustup.rs/)
$ rustup install stable$ rustup doc
Инсталация
- Rustup (https://rustup.rs/)
$ rustup install stable$ rustup doc- https://2017.fmi.rust-lang.bg/topics/1
- Може би на уиндоус нещата са една идея по-лесни днешно време: https://www.reddit.com/r/rust/comments/v9uciv/rustup_on_windows_will_soon_give_the_option_to/
Среда за разработка
Среда за разработка
- текстов редактор, който поддържа LSP (language server protocol)
Среда за разработка
- текстов редактор, който поддържа LSP (language server protocol)
- rust-analyzer
Среда за разработка
- текстов редактор, който поддържа LSP (language server protocol)
- rust-analyzer
rustup component add rust-analyzer
Среда за разработка
- текстов редактор, който поддържа LSP (language server protocol)
- rust-analyzer
rustup component add rust-analyzerrustup component add rustfmt
The Rust Book
Rust playpen
Променливи
Променливи се декларират с let
let NAME = VALUE;
let NAME: TYPE = VALUE;
let x = 5;
let y: i32 = 3;
#[allow(unused_variables)]
fn main() {
let x = 5;
let y: i32 = 3;
}
Променливи
Всяка променлива има тип, но можем да не пишем типа, ако е ясен от контекста
let x: i32 = 5;
let y = x; // типа на `y` е `i32`, защото `x` e `i32`
#[allow(unused_variables)]
fn main() {
let x: i32 = 5;
let y = x; // типа на `y` е `i32`, защото `x` e `i32`
}
let x = 5; // типа на `x` е `i32`, защото `y` e `i32`
let y: i32 = x;
#[allow(unused_variables)]
fn main() {
let x = 5; // типа на `x` е `i32`, защото `y` e `i32`
let y: i32 = x;
}
Променливи
Засенчване (shadowing)
Можем да декларираме нова променлива със същото име като вече съществуваща.
let x = 10;
let x = x + 10;
let x = x * 3;
println!("{}", x);
60
#[allow(unused_variables)]
fn main() {
let x = 10;
let x = x + 10;
let x = x * 3;
println!("{}", x);
}
Променливи
Засенчване (shadowing)
Предишното е еквивалентно на:
let x1 = 10;
let x2 = x1 + 10;
let x3 = x2 * 3;
println!("{}", x3);
60
#[allow(unused_variables)]
fn main() {
let x1 = 10;
let x2 = x1 + 10;
let x3 = x2 * 3;
println!("{}", x3);
}
Променливи
mutability
Променливите са immutable по подразбиране
let x = 5;
x += 1;
Променливи
mutability
Променливите са immutable по подразбиране
let x = 5;
x += 1;
error[E0384]: cannot assign twice to immutable variable `x` --> src/bin/main_7db00a1a92dd466b5d0d2e943c3247d86695e529.rs:6:1 | 5 | let x = 5; | - | | | first assignment to `x` | help: consider making this binding mutable: `mut x` 6 | x += 1; | ^^^^^^ cannot assign twice to immutable variable For more information about this error, try `rustc --explain E0384`. error: could not compile `rust` (bin "main_7db00a1a92dd466b5d0d2e943c3247d86695e529") due to 1 previous error
#[allow(unused_variables)]
#[allow(unused_assignments)]
fn main() {
let x = 5;
x += 1;
}
Променливи
mutability
За да се направи mutable се използва ключовата дума mut
let mut x = 5;
x += 1;
#[allow(unused_variables)]
#[allow(unused_assignments)]
fn main() {
let mut x = 5;
x += 1;
}
Променливи
mutability
Това е различно от shadowing!
let x = 5;
let x = x + 1;
#[allow(unused_variables)]
#[allow(unused_assignments)]
fn main() {
let x = 5;
let x = x + 1;
}
Основни типове
Целочислени типове
i8,i16,i32,i64,i128,isizeu8,u16,u32,u64,u128,usize
Основни типове
Целочислени типове
i8,i16,i32,i64,i128,isizeu8,u16,u32,u64,u128,usizeiN- цяло (signed) число с размер N битаuN- неотрицателно (unsigned) число с размер N бита
Основни типове
Целочислени типове
i8,i16,i32,i64,i128,isizeu8,u16,u32,u64,u128,usizeiN- цяло (signed) число с размер N битаuN- неотрицателно (unsigned) число с размер N битаisizeиusizeимат размер колкото машинната дума - 32 бита на 32 битов ОС и 64 бита на 64 битов ОС
Основни типове
Целочислени типове
i8,i16,i32,i64,i128,isizeu8,u16,u32,u64,u128,usizeiN- цяло (signed) число с размер N битаuN- неотрицателно (unsigned) число с размер N битаisizeиusizeимат размер колкото машинната дума - 32 бита на 32 битов ОС и 64 бита на 64 битов ОС
let x: u32 = 1337;
fn main() {
let x: u32 = 1337;
}
Основни типове
Целочислени типове (литерали)
Основни типове
Целочислени типове (литерали)
- Цяло число:
42 - Специфичен тип:
42u32
Основни типове
Целочислени типове (литерали)
- Цяло число:
42 - Специфичен тип:
42u32 - Големи числа:
133_587 1_000_000
Основни типове
Целочислени типове (литерали)
- Цяло число:
42 - Специфичен тип:
42u32 - Големи числа:
133_587 1_000_00042_u32
Основни типове
Целочислени типове (литерали)
- Цяло число:
42 - Специфичен тип:
42u32 - Големи числа:
133_587 1_000_00042_u321_0_0_0
Основни типове
Целочислени типове (литерали)
- Цяло число:
42 - Специфичен тип:
42u32 - Големи числа:
133_587 1_000_00042_u321_0_0_01_____________________________________________________4
Основни типове
Целочислени типове (литерали)
- Цяло число:
42 - Специфичен тип:
42u32 - Големи числа:
133_587 1_000_00042_u321_0_0_01_____________________________________________________4
let x: u32 = 1337;
let x = 1337_u32;
fn main() {
let x: u32 = 1337;
let x = 1337_u32;
}
Основни типове
Целочислени типове (в различни бройни системи)
- Hex:
0xDEADBEEF - Octal:
0o77 - Binary:
0b1010011010
Основни типове
Числа с плаваща запетая
f32f64- съответно 32 битов и 64 битов float
3.141.3_f64
Основни типове
Числа с плаваща запетая
f32f64- съответно 32 битов и 64 битов float
3.141.3_f64
let x: f64 = 3.14;
fn main() {
let x: f64 = 3.14;
}
Основни типове
Булеви стойности
bool- стойности
trueиfalse
let x: bool = true;
fn main() {
let x: bool = true;
}
Основни типове
unit
- тип
() - стойност
()
Основни типове
unit
- тип
() - стойност
() - тип с една единствена стойност
- големина 0 байта, не носи информация
- използва се за функции които не връщат стойност
- и на други места
Основни типове
unit
- тип
() - стойност
() - тип с една единствена стойност
- големина 0 байта, не носи информация
- използва се за функции които не връщат стойност
- и на други места
let x: () = ();
fn main() {
let x: () = ();
}
Основни типове
Низове
&str
Основни типове
Низове
&str- utf8 низ
- ще му обърнем повече внимание в бъдеща лекция.
Основни типове
Низове
&str- utf8 низ
- ще му обърнем повече внимание в бъдеща лекция.
let s = "Нещо си";
fn main() {
let s = "Нещо си";
}
Основни типове
Низове
&str- utf8 низ
- ще му обърнем повече внимание в бъдеща лекция.
let s = "Нещо си";
fn main() {
let s = "Нещо си";
}
let s: &str = "Нещо си";
fn main() {
let s: &str = "Нещо си";
}
Основни типове
Низове
&str- utf8 низ
- ще му обърнем повече внимание в бъдеща лекция.
let s = "Нещо си";
fn main() {
let s = "Нещо си";
}
let s: &str = "Нещо си";
fn main() {
let s: &str = "Нещо си";
}
let s: &'static str = "Нещо си";
fn main() {
let s: &'static str = "Нещо си";
}
Основни типове
Символи
char
Основни типове
Символи
char- unicode code point
- различно е от
u8 - ще му обърнем внимание заедно с низовете
Основни типове
Символи
char- unicode code point
- различно е от
u8 - ще му обърнем внимание заедно с низовете
let heart1: char = '❤';
let heart2: char = '\u{2764}';
let heart3: &str = "❤";
println!("{:?}", heart1);
println!("{:?}", heart2);
println!("{:?}", heart3);
'❤' '❤' "❤"
fn main() {
let heart1: char = '❤';
let heart2: char = '\u{2764}';
let heart3: &str = "❤";
println!("{:?}", heart1);
println!("{:?}", heart2);
println!("{:?}", heart3);
}
Основни типове
Масиви
[T; n]
let arr: [i32; 3] = [1, 2, 3];
let nested: [[i32; 3]; 2] = [
[1, 2, 3],
[4, 5, 6],
];
fn main() {
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: () = ();
println!("{}", tuple.0);
println!("{}", tuple.1);
println!("{}", tuple.2);
1 2 false
fn main() {
let tuple: (i32, u32, bool) = (1, 2, false);
let unit: () = ();
println!("{}", tuple.0);
println!("{}", tuple.1);
println!("{}", tuple.2);
}
Основни типове
Сравнение със 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 |
| Length | Rust | C++ |
|---|---|---|
| 8-bit | bool | bool |
| - | () | void |
Специфики
Няма автоматично конвертиране между различни числови типове
let x: i32 = 1;
let y: u64 = x;
error[E0308]: mismatched types --> src/bin/main_a6086f539401bbf3b7b549495af4885bf92b9c07.rs:4:14 | 4 | let y: u64 = x; | --- ^ expected `u64`, found `i32` | | | expected due to this | help: you can convert an `i32` to a `u64` and panic if the converted value doesn't fit | 4 | let y: u64 = x.try_into().unwrap(); | ++++++++++++++++++++ For more information about this error, try `rustc --explain E0308`. error: could not compile `rust` (bin "main_a6086f539401bbf3b7b549495af4885bf92b9c07") due to 1 previous error
fn main() {
let x: i32 = 1;
let y: u64 = x;
}
Специфики
Аритметични операции не могат да се прилагат върху различни типове
let x = 4_u32 - 1_u8;
error[E0308]: mismatched types --> src/bin/main_b74b848673d4adf9f397294b8a6806527e7fe9af.rs:3:17 | 3 | let x = 4_u32 - 1_u8; | ^^^^ expected `u32`, found `u8` error[E0277]: cannot subtract `u8` from `u32` --> src/bin/main_b74b848673d4adf9f397294b8a6806527e7fe9af.rs:3:15 | 3 | let x = 4_u32 - 1_u8; | ^ no implementation for `u32 - u8` | = help: the trait `Sub<u8>` is not implemented for `u32` = help: the following other types implement trait `Sub<Rhs>`: <&'a u32 as Sub<u32>> <&u32 as Sub<&u32>> <u32 as Sub<&u32>> <u32 as Sub> Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. error: could not compile `rust` (bin "main_b74b848673d4adf9f397294b8a6806527e7fe9af") due to 2 previous errors
fn main() {
let x = 4_u32 - 1_u8;
}
Специфики
Аритметични операции не могат да се прилагат върху различни типове
let y = 1.2_f64 / 0.8_f32;
error[E0308]: mismatched types --> src/bin/main_4b79085d5e1911494b6d393237ddd8eb8f7a9174.rs:3:19 | 3 | let y = 1.2_f64 / 0.8_f32; | ^^^^^^^ expected `f64`, found `f32` error[E0277]: cannot divide `f64` by `f32` --> src/bin/main_4b79085d5e1911494b6d393237ddd8eb8f7a9174.rs:3:17 | 3 | let y = 1.2_f64 / 0.8_f32; | ^ no implementation for `f64 / f32` | = help: the trait `Div<f32>` is not implemented for `f64` = help: the following other types implement trait `Div<Rhs>`: <&'a f64 as Div<f64>> <&f64 as Div<&f64>> <f64 as Div<&f64>> <f64 as Div> Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. error: could not compile `rust` (bin "main_4b79085d5e1911494b6d393237ddd8eb8f7a9174") due to 2 previous errors
fn main() {
let y = 1.2_f64 / 0.8_f32;
}
Специфики
За конвертиране между типове се използва ключовата дума as
let one = true as u8;
let two_hundred = -56_i8 as u8;
let three = 3.14 as u32;
println!("one: {}", one);
println!("two_hundred: {}", two_hundred);
println!("three: {}", three);
one: 1 two_hundred: 200 three: 3
#[allow(unused_variables)]
fn main() {
let one = true as u8;
let two_hundred = -56_i8 as u8;
let three = 3.14 as u32;
println!("one: {}", one);
println!("two_hundred: {}", two_hundred);
println!("three: {}", three);
}
Специфики
В режим debug, аритметични операции хвърлят грешка при препълванe (integer overflow / underflow)
let x = 255_u8;
let y = x + 1; // 💥
error: this arithmetic operation will overflow --> src/bin/main_da94a0a591bfa1baec52a2ac88263d791f73c1e2.rs:4:9 | 4 | let y = x + 1; // 💥 | ^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow | = note: `#[deny(arithmetic_overflow)]` on by default error: could not compile `rust` (bin "main_da94a0a591bfa1baec52a2ac88263d791f73c1e2") due to 1 previous error
#[allow(unused_variables)]
fn main() {
let x = 255_u8;
let y = x + 1; // 💥
}
Специфики
В режим debug, аритметични операции хвърлят грешка при препълванe (integer overflow / underflow)
let x = std::convert::identity(255_u8);
let y = x + 1; // 💥
thread 'main' panicked at src/bin/main_c946d84a33b010ec376589498d5067ba9828b4b9.rs:4:9: attempt to add with overflow note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
#[allow(unused_variables)]
fn main() {
let x = std::convert::identity(255_u8);
let y = x + 1; // 💥
}
Специфики
Няма оператори ++ и --
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 {
// ...
}
if 2 > 1 {
println!("okay");
} else {
println!("wait what");
}
fn main() {
let bool_expression = true;
let another_bool_expression = false;
if bool_expression {
// ...
} else if another_bool_expression {
// ...
} else {
// ...
}
if 2 > 1 {
println!("okay");
} else {
println!("wait what");
}
}
Забележете, че няма скоби около условието и скобите за блок { } са задължителни.
Control flow
Цикли
for цикъла работи с итератори, за които ще говорим в бъдеща лекция
for var in iterable {
// ...
}
for n in [1, 2, 3] {
println!("N: {}", n);
}
fn main() {
let iterable: &[()] = &[];
for var in iterable {
// ...
}
for n in [1, 2, 3] {
println!("N: {}", n);
}
}
Отново няма скоби след for и скобите за блок { } са задължителни.
Control flow
Цикли
Също така има и while и loop цикли.
while bool_expression {
// ...
}
fn main() {
let bool_expression = false;
while bool_expression {
// ...
}
}
loop e същото като while true, но по-четимо.
loop {
// ...
}
fn main() {
loop {
// ...
}
}
Control flow
Цикли
'outer: for x in [1, 2, 3] {
'inner: for y in [4, 5, 6] {
if some_condition {
break 'outer;
}
// ...
}
}
#![allow(unused_labels)]
fn main() {
let some_condition = false;
'outer: for x in [1, 2, 3] {
'inner: for y in [4, 5, 6] {
if some_condition {
break 'outer;
}
// ...
}
}
}
- могат да се слагат етикети на циклите
- етикетите могат да се подават на
breakиcontinue
Statements & Expressions
Израз (expression)
Код, който може да се оцени до някаква стойност.
Тази стойност може да се присвои на променлива или да се използва като част от по-голям израз.
Statements & Expressions
Израз (expression)
Код, който може да се оцени до някаква стойност.
Тази стойност може да се присвои на променлива или да се използва като част от по-голям израз.
1
Statements & Expressions
Израз (expression)
Код, който може да се оцени до някаква стойност.
Тази стойност може да се присвои на променлива или да се използва като част от по-голям израз.
1(2 + 3) * 4
Statements & Expressions
Израз (expression)
Код, който може да се оцени до някаква стойност.
Тази стойност може да се присвои на променлива или да се използва като част от по-голям израз.
1(2 + 3) * 4add(5, 6)
Statements & Expressions
Твърдение (statement)
Декларация, която указва какво трябва да се направи.
Няма стойност, ами предизвиква някакъв страничен ефект.
Statements & Expressions
Твърдение (statement)
Декларация, която указва какво трябва да се направи.
Няма стойност, ами предизвиква някакъв страничен ефект.
let x = 10;
Statements & Expressions
Твърдение (statement)
Декларация, която указва какво трябва да се направи.
Няма стойност, ами предизвиква някакъв страничен ефект.
let x = 10;fn add(a: i32, b: i32) { a + b }
Statements & Expressions
Твърдение (statement)
Декларация, която указва какво трябва да се направи.
Няма стойност, ами предизвиква някакъв страничен ефект.
let x = 10;fn add(a: i32, b: i32) { a + b }return 25;
Statements & Expressions
Твърдение (statement)
Декларация, която указва какво трябва да се направи.
Няма стойност, ами предизвиква някакъв страничен ефект.
let x = 10;fn add(a: i32, b: i32) { a + b }return 25;израз;
Statements & Expressions
Твърдение (statement)
Пример: можем да присвояваме стойността на израз на променлива с let, но не и стойността на твърдение (защото няма стойност)
let x = (fn add(a: i32, b: i32) { a + b });
error: expected expression, found keyword `fn` --> src/bin/main_c555e6093e9298bc6b5bd3b51338a44a54a824ad.rs:3:10 | 3 | let x = (fn add(a: i32, b: i32) { a + b }); | ^^ expected expression error: could not compile `rust` (bin "main_c555e6093e9298bc6b5bd3b51338a44a54a824ad") due to 1 previous error
#![allow(unused_parens)]
fn main() {
let x = (fn add(a: i32, b: i32) { a + b });
}
Statements & Expressions
Много от конструкциите на езика са изрази.
Блоковете са израз - стойността им е стойността на последния израз в блока
fn main() {
let x = {
let a = 1;
let b = 2;
a + b
};
println!("x = {}", x);
}
x = 3
fn main() {
let x = {
let a = 1;
let b = 2;
a + b
};
println!("x = {}", x);
}
Statements & Expressions
if-else конструкцията е израз
let bigger = if a > b {
a
} else {
b
};
#[allow(unused_variables)]
fn main() {
let a = 1; let b = 2;
let bigger = if a > b {
a
} else {
b
};
}
По тази причина няма тернарен оператор
let bigger = if a > b { a } else { b };
#[allow(unused_variables)]
fn main() {
let a = 1; let b = 2;
let bigger = if a > b { a } else { b };
}
Statements & Expressions
loop е израз
let x = loop {
break 5;
};
#[allow(unused_variables)]
fn main() {
let x = loop {
break 5;
};
}
Но for и while не са.
Statements & Expressions
Блокове с етикети
fn main() {
let x = 'label: {
if is_error {
break 'label 0;
}
let a = 1;
let b = 2;
a + b
};
println!("x = {}", x);
}
x = 3
fn main() {
let is_error = false;
let x = 'label: {
if is_error {
break 'label 0;
}
let a = 1;
let b = 2;
a + b
};
println!("x = {}", x);
}
- етикети могат да се слагат и на блокове
break 'labelпозволява "ранно връщане" от блок със стойност
Statements & Expressions
Блокове с етикети
fn main() {
let x = 'label: {
if is_error {
break 'label 0;
}
let a = 1;
let b = 2;
a + b
};
println!("x = {}", x);
}
x = 3
fn main() {
let is_error = false;
let x = 'label: {
if is_error {
break 'label 0;
}
let a = 1;
let b = 2;
a + b
};
println!("x = {}", x);
}
- етикети могат да се слагат и на блокове
break 'labelпозволява "ранно връщане" от блок със стойност- помислете дали не е по-четимо да изведете кода в отделна функция
Функции
fn main() {
println!("Hello, world!");
another_function();
}
fn another_function() {
println!("Another function.");
}
Hello, world! Another function.
fn main() {
println!("Hello, world!");
another_function();
}
fn another_function() {
println!("Another function.");
}
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
fn main() {}
#[allow(dead_code)]
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
fn main() {}
#[allow(dead_code)]
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
- Задаването на типове на параметрите и резултата е задължително
Функции
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
fn main() {}
#[allow(dead_code)]
fn add(a: u32, b: u32) -> u32 {
// note no semicolon
a + b
}
- Задаването на типове на параметрите и резултата е задължително
- Върнатата стойност е стойността на последния израз в тялото на функцията
Функции
fn print_a(a: u32) {
println!("{}", a);
}
fn print_b(b: u32) -> () {
println!("{}", b);
}
fn main() {}
#[allow(dead_code)]
fn print_a(a: u32) {
println!("{}", a);
}
#[allow(dead_code)]
fn print_b(b: u32) -> () {
println!("{}", b);
}
- Не е нужно да пишем
-> ()за функции който не връщат резулат
Функции
fn good_a(a: u32, a_is_bad: bool) -> u32 {
if a_is_bad {
return 0;
}
a
}
fn main() {}
#[allow(dead_code)]
fn good_a(a: u32, a_is_bad: bool) -> u32 {
if a_is_bad {
return 0;
}
a
}
- Ако искаме да излезем от функцията преди последния ред, може да използваме
return - Използване на
returnна последния ред от тялото се счита за лоша практика
Анонимни функции (closures)
fn add1(a: u32, b: u32) -> u32 {
a + b
}
fn main() {
let add2 = |a, b| { a + b };
println!("add1: {}\nadd2: {}", add1(1, 2), add2(1, 2));
}
add1: 3 add2: 3
fn add1(a: u32, b: u32) -> u32 {
a + b
}
fn main() {
let add2 = |a, b| { a + b };
println!("add1: {}\nadd2: {}", add1(1, 2), add2(1, 2));
}
- Ще говорим доста повече за тях по-нататък
Macros
- служат за генериране на код
- различават се от функциите по
!след името
Macros
- служат за генериране на код
- различават се от функциите по
!след името println!print!dbg!
println! macro
let x = 5;
let y = "десет";
println!("x = {} and y = {}", x, y);
x = 5 and y = десет
fn main() {
let x = 5;
let y = "десет";
println!("x = {} and y = {}", x, y);
}
println! macro
let x = 5;
let y = "десет";
println!("x = {} and y = {}", x, y);
x = 5 and y = десет
fn main() {
let x = 5;
let y = "десет";
println!("x = {} and y = {}", x, y);
}
- Принтиране на конзолата
println! macro
let x = 5;
let y = "десет";
println!("x = {} and y = {}", x, y);
x = 5 and y = десет
fn main() {
let x = 5;
let y = "десет";
println!("x = {} and y = {}", x, y);
}
- Принтиране на конзолата
{}placeholders
println! macro
let x = 5;
let y = "десет";
println!("x = {:?} and y = {:?}", x, y);
x = 5 and y = "десет"
fn main() {
let x = 5;
let y = "десет";
println!("x = {:?} and y = {:?}", x, y);
}
- Принтиране на конзолата
{:?}placeholders
println! macro
let x = 255;
let y = 10;
println!("x = {:x} and y = {:04}", x, y);
x = ff and y = 0010
fn main() {
let x = 255;
let y = 10;
println!("x = {:x} and y = {:04}", x, y);
}
{:x}и{:0}placeholders и всевъзможни други (std::fmt)
println! macro
let var_x = 5;
let var_y = "десет";
println!("имам {var_x} и {var_y}"); // e еквивалентно на
println!("имам {} и {}", var_x, var_y);
println!("имам {var_x:?} и {var_y:?}"); // е еквивалентно на
println!("имам {:?} и {:?}", var_x, var_y);
имам 5 и десет имам 5 и десет имам 5 и "десет" имам 5 и "десет"
fn main() {
let var_x = 5;
let var_y = "десет";
println!("имам {var_x} и {var_y}"); // e еквивалентно на
println!("имам {} и {}", var_x, var_y);
println!("имам {var_x:?} и {var_y:?}"); // е еквивалентно на
println!("имам {:?} и {:?}", var_x, var_y);
}
- могат да се пишат имена на променливи директно в
{}placeholder-а, вместо да се подават като отделни аргументи - но не могат да се пишат по-сложни изрази
dbg! macro
let x = 5;
let y = "десет";
dbg!(x);
dbg!(y);
[src/bin/main_72fe3d84fb206495b3ff0c4f73c4dc2f69e38ea2.rs:5:1] x = 5 [src/bin/main_72fe3d84fb206495b3ff0c4f73c4dc2f69e38ea2.rs:6:1] y = "десет"
fn main() {
let x = 5;
let y = "десет";
dbg!(x);
dbg!(y);
}
Административни неща
- Инсталирайте си Rust: https://2017.fmi.rust-lang.bg/topics/1
Административни неща
- Инсталирайте си Rust: https://2017.fmi.rust-lang.bg/topics/1
- Елате в Discord канала: https://discord.gg/r9Wcazk
Административни неща
- Инсталирайте си Rust: https://2017.fmi.rust-lang.bg/topics/1
- Елате в Discord канала: https://discord.gg/r9Wcazk
- Fun fact: ако си качите снимка в сайта, ще получите 1 бонус точка
Материали
- Ако си търсите книжки: https://bitfieldconsulting.com/posts/best-rust-books