Rust: Getting Started
Reference
- Documentation:
Hello World
1 | fn main(){ |
- Run:
rustc <file.rs>
- Debug:
rust-gdb
- Unmangle:
rustfilt
1 | strace -f -e trace=file -o log.txt rustc hello.rs |
What is this?
/home/ethanol/.rustup/toolchains/
Macro in C++?
Abstract syntax tree?
fdump-tree-all-graph
Dumping pre-compile stuff
- Documentation: https://doc.rust-lang.org/rustc/command-line-arguments.html#--emit-specifies-the-types-of-output-files-to-generate
1
rustc --emit=dep-info,llvm-ir,asm hello.rs
- Documentation: https://doc.rust-lang.org/rustc/command-line-arguments.html#--emit-specifies-the-types-of-output-files-to-generate
cargo-expand
1
2
3
4
5
6
7
8
9
10#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
{
::std::io::_print(format_args!("Hello, world!\n"));
};
}
Note
- You can’t use unstable features with stable/beta
rustc
. You need a nightly build for that. - Bound checking?
Integer overflow
When you’re compiling in release mode with the --release
flag, Rust does not include checks for integer overflow that cause panics. Instead, if overflow occurs, Rust performs two’s complement wrapping. In short, values greater than the maximum value the type can hold “wrap around” to the minimum of the values the type can hold. In the case of a u8
, the value 256 becomes 0, the value 257 becomes 1, and so on.
- Wrap in all modes with the
wrapping_*
methods, such aswrapping_add
. - Return the
None
value if there is overflow with thechecked_*
methods. - Return the value and a boolean indicating whether there was overflow with the
overflowing_*
methods. - Saturate at the value’s minimum or maximum values with the
saturating_*
methods.
Crypto —> Wrap
Computer graphics —> SaturateDebugging
1
2
3
4
5
6
7
8
9
10rust-gdb
rustfilt <- unmangling
cargo install cargo-expand
cargo expand
file <binary>
hexdump -C
objdump -x
strace -f -e trace=file -o log.txt rustc hello.rsQuestions
Q: What is Result<T, BmpError>
and what is enum?
1 | pub type BmpResult<T> = Result<T, BmpError>; |
A: Result is an enum, and enums are like unions in C/C++, but a bit smarter.
https://doc.rust-lang.org/std/result/
https://doc.rust-lang.org/src/core/result.rs.html#502
Q: What is trait
1 | pub trait Debug { |
Q: The mechanism of the conversion from integer 64 to a string
1 | ::core::fmt::Formatter::debug_tuple_field1_finish(f, "A", &__self_0) |
Q: println formatting
fmt::Debug
: Uses the{:?}
marker. Format text for debugging purposes.fmt::Display
: Uses the{}
marker. Format text in a more elegant, user friendly fashion.
Q: writeln formatting
Q: macro syntax in Rust
Q: Lifetime annotation
Stuff
#[this is an attribute]
OuterAttribute vs InnerAttribute
- Placement: Inner attributes are placed inside the item and use #![…], while outer attributes are placed outside (above) the item and use #[…].
- Scope: Inner attributes typically apply to the module or crate they are placed in, while outer attributes apply to the item they precede.
- Usage: Outer attributes are more commonly used for deriving traits, enabling compiler lints, and other item-level metadata, while inner attributes are often used for crate-level configuration or module-level settings.
Variadic functions vs macro in Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16macro_rules! sum {
($($num:expr),*) => {
{
let mut total = 0;
$(
total += $num;
)*
total
}
};
}
fn main() {
let result = sum!(1,2,3,4,5);
println!("The sum is: {}", result);
}Basically for Result the
.unwrap()
is the same as.expect("ERROR MESSAGE")
with the exception of the error message.And the
asdf()?
mean “ifasdf()
returns Result or Option, and current function also does so, the return from this function in case of an error passing the Result/Option further along”The question mark operator (
?
) can only be used in a function that returnsResult
orOption
.1
2
3
4
5
6
7
8fn main() {
let x: i32 = "12".parse()?; // Error because main function does not return Return or Option
}
fn parse_int() -> Result<i32, ParseIntError> {
let x: i32 = "12".parse()?; // x = 12
let y: i32 = "12a".parse()?; // return Err() immediatly ---> Not error
}Tuple syntax
1
2let x: (i32, f64, u8) = (500, 6.4, 1);
let asdf = x.2;Command
Cargo expand is doing basically
gcc -E
1
2cargo install cargo-expand
cargo expand
Implement linked-list is nightmare
1 | https://github.com/aodr3w/double-rs/blob/main/src/doubly.rs |
- Ownership
- Smart pointer
- Trait
- Fearless concurrency
It’s time to read Rust book…
Some fun
- In Java, Slice -> Ref Count += 1 -> No use -> but still reference -> GC cannot collect
- In python -> slice copy