Learning the Rust Programming Language

Source: The Rust Programming Language by Steve Klabnik and Carol Nichols (pdf) - Rust 1.50 / 2018

Table of Contents

Enable Javascript to display Table of Contents.

Foreword

Marketing bla blub

Introduction

Getting Started - Installation

Rust can be installed in different ways, this shows the installation with rustup:
$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

[...]

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1

[...]

To configure your current shell, run:
source $HOME/.cargo/env
$
$ source $HOME/.cargo/env
$ rustc --version
rustc 1.53.0 (53cb7b09b 2021-06-17)
$ 
$ cp .profile .profile.orig
$ cp .bashrc .bashrc.orig
$
$ # install rust
$
$ diff .profile.orig .profile
27a28
> . "$HOME/.cargo/env"
$ diff .bashrc.orig .bashrc
128a129
> . "$HOME/.cargo/env"
$ 
The changes to .profile and .bashrc are limited to sourcing the environment file.

Rust can be updated by rustup update and uninstalled by rustup self uninstall. rustup doc will open the documentation in a web browser.

Getting Started - Hello World!

fn main() {
    println!("Hello, world!");
}
$ mkdir Projects/playground/hello_rust
$ cd Projects/playground/hello_rust
$ vi main.rs
$ rustc main.rs 
$ ls
main  main.rs
$ ./main 
Hello, world!
$ file main
main: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0,
BuildID[sha1]=fcf290d46f244d46f80e05c5e5fa97eff197144b, with debug_info, not stripped
$ 
$ cat main.rs 
fn
main()
{
println!(
		"Hello, world!"
	
	);
}
$ rustc main.rs      # compiles !
$ rustfmt main.rs    # format with standard style
$ cat main.rs 
fn main() {
    println!("Hello, world!");
}
$ 

Getting Started - Hello Cargo!

Creating a new Rust project can be done with cargo like this:
$ cargo new hello_cargo
     Created binary (application) `hello_cargo` package
$ cd hello_cargo/
$ tree -a
.
├── Cargo.toml
├── .git
│   [...]
├── .gitignore
└── src
    └── main.rs

10 directories, 18 files
$ 
$ cat Cargo.toml 
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
$ 
$ cargo build
   Compiling hello_cargo v0.1.0 (/home/krach/Projects/playground/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.35s
$
$ ./target/debug/hello_cargo 
Hello, world!
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/hello_cargo`
Hello, world!
$ 
$ touch src/main.rs 
$ cargo run
   Compiling hello_cargo v0.1.0 (/home/krach/Projects/playground/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/hello_cargo`
Hello, world!
$ 

Programming a Guessing Game

First we create a new project...
21:49:26[rust]$ rustc --version
rustc 1.51.0
21:49:34[rust]$ cargo new guessing_game
     Created binary (application) `guessing_game` package
21:49:55[rust]$
And compiling and running the code...
21:49:55[rust]$ cd guessing_game/
21:51:02[guessing_game]$ cargo run
   Compiling guessing_game v0.1.0 (/home/charly/tmp/rust/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 0.70s
     Running `target/debug/guessing_game`
Hello, world!
21:51:18[guessing_game]$ 
In the next steps we expend the code:

Crates

Adding the single rand library adds 9 implicit dependencies:
10:48:03[guessing_game]$ cat Cargo.lock | grep package | wc -l
1
10:48:15[guessing_game]$ ls -l target/debug/guessing_game
-rwxrwxr-x 2 charly charly 10794144 Aug 28 22:01 target/debug/guessing_game
10:48:19[guessing_game]$ gvim Cargo.toml 
10:48:25[guessing_game]$ git diff --unified=0 Cargo.toml | tail -n +5
@@ -9,0 +10 @@ edition = "2018"
+rand = "0.8.3"
10:48:45[guessing_game]$ cargo build
    Updating crates.io index
    Finished dev [unoptimized + debuginfo] target(s) in 0.83s
10:48:53[guessing_game]$ ls -l target/debug/guessing_game
-rwxrwxr-x 2 charly charly 10794152 Aug 29 10:39 target/debug/guessing_game
10:48:55[guessing_game]$ 
10:48:58[guessing_game]$ cat Cargo.lock | grep package | wc -l
10
10:49:00[guessing_game]$ 

Error Handling

When a method returns a value of type Result the compiler generates a warning when the error-code is not checked. This can be done in two ways. When an error is not expected, the expect() method can be used - it works like an assert and crashes the program when an error appears:
let guess: u32 = guess.trim().parse().expect("Please type a number!");

When it is likely that the method returns an error - e.g. in user-interaction - the error shall be handled:

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(e) => {
                println!("Got invalid input: {}", e);
                continue
            },
        };

Common Programming Concepts - Variables and Mutability

Common Programming Concepts - Data Types

Common Programming Concepts - Functions

Common Programming Concepts - Comments

not worth reading

Common Programming Concepts - Control Flow