Because why not!?
Rust is syntactically similar to C, so there are for
loops, semicolon
terminated statements, and blocks formed by curly braces. Rust is statically
typed, meaning that a variable can never change its type but you don't always
have to declare a variable's type in Rust because the compiler can often figure
it out from the context. Variables in Rust are immutable by default.
Functions are first-class values, like in functional programming languages.
Rust is not an object-oriented language, as there are no classes or inheritance
in Rust. Instead, Rust uses a struct
(structure) to represent complex data
types and traits to describe how types can behave. These structures can have
methods, can mutate the internal state of the data, and might even be called
objects in the documentation, but they are not objects in the formal sense of
the word.
Rust can guarantee memory safety through the use of a borrow checker that tracks which part of a program has safe access to different parts of memory and this safety does not come at the expense of performance.
Rust programs compile to native binaries and often match or beat the speed of programs written in C or C++. For these reasons, Rust is often described as a systems programming language that has been designed for performance and safety.
Rust can be installed using rustup
, which is a command line tool for managing
Rust versions and associated tools. Open a terminal, enter the command below
and follow the prompt.
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
Rust is installed now. Great!
To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).
To configure your current shell, run:
source "$HOME/.cargo/env"
source "$HOME/.cargo/env"
rustc --version
rustc 1.71.1 (eb26296b5 2023-08-03)
To update.
rustup update
To uninstall.
rustup self uninstall
Use the official Docker image.
docker pull rust:1.64.0
docker run --rm rust:1.64.0 cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
Use script/start_container.sh
to start and restart a container using
rust:1.64.0 called learning_rust
.
The Rust compiler is rustc
. Compile the hello world example by running:
rustc eg/hello.rs
./hello
# Hello, world!
Determine file type.
file ./hello
# ./hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=81ba1f0be3c7a8c64dfc5e3e05959affe202f9a3, not stripped
Cargo is Rust's build tool, package manager, and test runner. You can use it to
start a new Rust project. The src
directory is for source code files and
main.rs
is the default starting point.
cargo new new_project
# Created binary (application) `new_project` package
tree --charset ascii new_project/
# new_project/
# |-- Cargo.toml
# `-- src
# `-- main.rs
#
# 1 directory, 2 files
Cargo.toml
is a configuration file for the project and stands for Tom's
Obvious, Minimal Language.
[package]
name = "new_project"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
The edition
key is the edition of Rust that should be used to compile the
program. Editions are how the Rust community introduces changes that are not
backward compatible.
Use cargo run
(in the project root directory) to compile and run or else
you'll get the following error error: could not find Cargo.toml in /work or any parent directory
. Use cargo build
for just building and not running.
cd new_project
cargo run
# Compiling new_project v0.1.0 (/home/dtang/github/learning_rust/new_project)
# Finished dev [unoptimized + debuginfo] target(s) in 0.20s
# Running `target/debug/new_project`
# Hello, world!
By default, Cargo will build a debug
target and there will be a
target/debug
directory containing the build artifacts. Use cargo clean
to
remove the target directory.
You can get help on any of Cargo's commands using:
cargo help command
Inside-out or unit testing is when you write tests for the functions inside
your program. Outside-in or integration testing is when you write tests that
run your programs. The convention in Rust projects is to create a tests
directory in the same level as src
.
Save the code below in a file inside tests
and run cargo test
.
#[test]
fn works() {
assert!(true);
}
The #[test]
attribute tells Rust to run this function when testing and the
assert!
macro asserts that a Boolean expression is true. There is another
macro called assert_eq!
that is used to verify that something is an expected
value.
Below is another test that executes a command and checks the result.
// import from the standard library
use std::process::Command;
#[test]
fn runs() {
// let will bind a value to a variable
// mut makes the variable mutable
// by default, Rust variables are immutable
let mut cmd = Command::new("ls");
// capture output as a Result
let res = cmd.output();
// verify that the result is an OK variant
assert!(res.is_ok());
}
Add the following lines to Cargo.toml
. The dev-dependencies
indicates that
this crate is only used for testing and benchmarking.
[dev-dependencies]
assert_cmd = "1"
Cargo commands.
- Create a project using
cargo new
. - Build a project using
cargo build
. - Build and run a project using
cargo run
. - Build a project without producing a binary to check for errors using
cargo check
; this is faster thancargo build
and is useful for testing. - Run tests inside
tests
usingcargo test
- Compile with optimisations using
cargo build --release
; this executable is much faster but takes longer to compile so use it only when you are ready for release. - To remove the target directory, use
cargo clean
. - To update a crate, use
cargo update
, which will ignore the Cargo.lock file and figure out all the latest versions that fit the specifications in Cargo.toml.
A crate is a collection of Rust source code files. There is a binary crate, which is an executable and there is a library crate, which contains code that is intended for use in other programs and can't be executed on its own. Crates are expected to use semantic version numbers in the form major.minor.patch.
Edit Cargo.toml
to add a dependency.
[dependencies]
rand = "0.8.5"
The specifier 0.8.5
is a shorthand for ^0.8.5
, which means any version that
is at least 0.8.5 but below 0.9.0.
- For parsing command-line arguments, use clap (command-line argument parser).
- A trait in Rust is a way to define the behaviour of an object in an
abstract way. For example, if an object implements the
Display
trait, then it can be formatted for user-facing output.
"The key feature of Rust is a concept of ownership and borrowing of variables, that enables the compiler to automatically decide about lifetime of objects during compile time, making an online memory management superfluous without requiring manual freeing of resources. At the same time, this concept prevents common sources of errors with low-level languages like accessing invalid memory regions. Finally, the ownership concept enforces thread-safety, such that race conditions cannot occur. These features make Rust a promising solution to above tradeoff problem."
- freeCodeCamp's complete Rust programming course (14-hour watch).
- Rust-bio, a bioinformatics library for Rust