Здравей, 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-analyzer
rustup 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
,isize
u8
,u16
,u32
,u64
,u128
,usize
Основни типове
Целочислени типове
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 битов ОС
Основни типове
Целочислени типове
i8
,i16
,i32
,i64
,i128
,isize
u8
,u16
,u32
,u64
,u128
,usize
iN
- цяло (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_000
42_u32
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
- Големи числа:
133_587
1_000_000
42_u32
1_0_0_0
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
- Големи числа:
133_587
1_000_000
42_u32
1_0_0_0
1_____________________________________________________4
Основни типове
Целочислени типове (литерали)
- Цяло число:
42
- Специфичен тип:
42u32
- Големи числа:
133_587
1_000_000
42_u32
1_0_0_0
1_____________________________________________________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
Основни типове
Числа с плаваща запетая
f32
f64
- съответно 32 битов и 64 битов float
3.14
1.3_f64
Основни типове
Числа с плаваща запетая
f32
f64
- съответно 32 битов и 64 битов float
3.14
1.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) * 4
add(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