Rust in Action v1.0
Rust in Action v1.0
Chapter – 01
Rust installation
$ curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf -o rust_setup.sh
$ ./rust_setup.sh
Rust Update
$ rustup update
Rust Uninstall
$ rustup self uninstall
Cargo:
Cargo is Rust’s (1) build system and (2) package manager.
Cargo:
o Builds your code
o Download and build the libraries /dependencies.
$ cargo --version
$ cd hello_cargo
Cargo has generated two files and one directory for us:
Cargo.toml file and a src directory with a main.rs file inside.
It has also initialized a new Git repository along with a .gitignore file.
Cargo.toml file is in the TOML (Tom’s Obvious, Minimal Language) format, which is Cargo’s configuration format.
Cargo.toml describes the project’s metadata, such as the
1. Project’s name,
2. Its version, and
3. Its dependencies.
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
[dependencies]
The first line, [package], is a section heading that indicates that the following statements are configuring a
package.
In Rust, packages are referred to as crates.
### Building and Running a Cargo Project ###
$ cargo build
$ cargo run
$ cargo check
$ cargo build --release
1 directory, 2 files
block3 /root/rust/hello_world # cargo run
Compiling hello_world v0.1.0 (/root/rust/hello_world)
Finished dev [unoptimized + debuginfo] target(s) in 1.74s
Running `target/debug/hello_world`
Hello, world!
block3 /root/rust # tree hello_world
hello_world
├── Cargo.lock
├── Cargo.toml
├── src
│ └── main.rs
└── target
├── CACHEDIR.TAG
└── debug
├── build
├── deps
│ ├── hello_world-41309fa5631cf679
│ └── hello_world-41309fa5631cf679.d
├── examples
├── hello_world
├── hello_world.d
└── incremental
└── hello_world-piieziagd64g
├── s-gf11eev05t-b8gy7z-3dgcwcgxcvw94
│ ├── 17shh8yjp31t9tyr.o
│ ├── 1b6ydeni2b79s1xb.o
│ ├── 1oobr0kbynjc5z0d.o
│ ├── 2d12tio9maj7d8ty.o
│ ├── 2oj6d9jlshlxum4j.o
│ ├── 3j7hh9aw5aybsehd.o
│ ├── 47gw2ue69elo3h9v.o
│ ├── 4c2488d0zcqpcvb4.o
│ ├── dep-graph.bin
│ ├── query-cache.bin
│ └── work-products.bin
└── s-gf11eev05t-b8gy7z.lock
9 directories, 20 files
Cargo.lock is a file that specifies the exact version numbers of all the dependencies so that future builds
are reliably built the same way until Cargo.toml is modified.
One of the first things that you are likely to notice is that strings in Rust are able to include a wide range of
characters.
Strings are guaranteed to be encoded as UTF-8
Macros can be thought of as fancy functions for now. These offer the ability to avoid boilerplate code.
In the case of println!, there is a lot of type detection going on under the hood so that arbitrary data types can
be printed to the screen.
// The backslash (\) allows the string to span multiple lines without inserting newlines.
// This converts the penguin_data string into an iterator of lines using the lines() method,
where each line of text becomes a separate element in the iterator.
// The enumerate() method is used to return both the index (i) and the line (record), as a tuple
if i == 0 || record.trim().len() == 0 { // <3>
// The .trim() function in Rust removes any leading and trailing whitespace (spaces, tabs,
newlines, etc.) from a string slice.
continue;
}
// This defines a vector fields, which will store the split components of the record (a line from
penguin_data).
.split(',') // <5>
// This splits the record string into parts based on commas (,). For example, "Little penguin,33"
becomes ["Little penguin", "33"].
// This map() function applies a closure to each field resulting from the split(). The closure
trims any leading or trailing whitespace from each field.
.collect(); // <7>
// The collect() function gathers the processed fields into a Vec<_>, which becomes a vector
fields containing the split and trimmed values of each line.
if cfg!(debug_assertions) { // <8>
//This checks if the code is being compiled in debug mode. cfg!(debug_assertions) evaluates to
true only when debug assertions are enabled (e.g., when compiling with cargo build --debug).
// This attempts to parse the second element of fields (the length) as a floating-point number
(f32). The if let Ok(length) syntax checks if the parsing succeeds (Ok), and if so, it assigns
the result to length.
Listing 1.3
rustc --explain E0382