Mike Slinn

Rust

Published 2024-05-30.
Time to read: 5 minutes.

This page is part of the posts collection, categorized under Rust.

Rust is a low-level programming language done right, using modern tools with good documentation and extensive support.

I have a lot of experience with the Scala and Ruby languages, as well as dozens of other computer languages. I believe that Rust has adopted the best parts of the Scala and Ruby philosophies and melded the syntaxes together nicely. For example, all of these languages provide expressions, closures, structs (value classes) and generics.

The package management is a bit like Ruby’s gems. Cargo crates and Ruby gems are provided as source code and compiled on demand.

Rust has many of the Scala features I enjoy the most:

What sets Rust apart, however, is:

  1. Error handling.
  2. Data ownership (borrow checker) and smart pointers.
  3. Data has lifetimes.
  4. Stable, yet advanced compile-time metaprogramming (macros).
  5. No runtime types.
  6. Unsafe system.
  7. Memory safety without a garbage collector; eal-time behavior is deterministic. Real-time audio/video applications are therefore possible.

rust-lang.org is the home of the Rust language.

Background

Rust was initially released in May 2015 by Graydon Hoare (no relation to Tony Hoare). Graydon had created the Swift language used by Apple the previous year. Chris Krycho has written a detailed comparison of the Swift and Rust languages.

Microsoft vice president David Weston said on Apr 29, 2023 that Microsoft had rewritten 36,000 lines of code in the Windows kernel in Rust, in addition to another 152,000 lines of code it had written for a proof of concept involving the DirectWrite Core library. The performance is purportedly excellent, with no regressions compared to the old C++ code.

Linus Torvalds accepts contributions for Linux written in Rust, and the Rust infrastructure now present in most Linux installations is mature. Linux 6.8, released on March 10, 2024, was the first version of Linux to include a device driver written in Rust, replacing an older network device driver written in C.

The XKCD Rust API looks like a fun way to blow off an afternoon.

If you need help, see the #beginners Rust Discord channel and the Rust Users Forum.

Bindings To Other Languages

  • Ruby / Rust bindingsMagnus allows you to write Ruby gems in Rust, and call Ruby code from Rust code.
  • Python / Rust bindings.Py03 allows you to mix Rust with Python. Enjoy Python’s convenience with Rust’s speed.
  • Calling C from Rust.
  • How to create C binding for a Rust library: Rust can generate C dynamic libraries (.so files) as well as static libraries (.a files), which can be easily wrapped in Go bindings and Python bindings and used in code written in those languages.
  • bindgen automatically generates Rust FFI bindings to C (and some C++) libraries.
  • Robusta — easy interoperability between Rust and Java. This library provides a procedural macro to make it easier to write JNI-compatible code in Rust and automatically convert Rust input and output types.
  • Execute a shell command from Rust.

rustup

Rustup is an installer for the Rust systems programming language.

WSL / Ubuntu

For WSL / Ubuntu you can easily install rustup, then install the Rust toolchain with the following commands:

Shell
$ yes | sudo apt install rustup
$ rustup default stable info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu' info: latest update on 2024-05-02, rust version 1.78.0 (9b00956e5 2024-04-29) info: downloading component 'cargo' info: downloading component 'clippy' info: downloading component 'rust-docs' info: downloading component 'rust-std' info: downloading component 'rustc' 63.7 MiB / 63.7 MiB (100 %) 38.2 MiB/s in 1s ETA: 0s info: downloading component 'rustfmt' info: installing component 'cargo' info: installing component 'clippy' info: installing component 'rust-docs' info: installing component 'rust-std' 24.3 MiB / 24.3 MiB (100 %) 23.8 MiB/s in 1s ETA: 0s info: installing component 'rustc' 63.7 MiB / 63.7 MiB (100 %) 20.5 MiB/s in 2s ETA: 0s info: installing component 'rustfmt' info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'
stable-x86_64-unknown-linux-gnu installed - rustc 1.78.0 (9b00956e5 2024-04-29)

Other OSes

Installation instructions for your computer's OS appear when you visit rustup.rs.

If you want to customize your setup, you need to know the host triple for your system. A ‘host triple’ identifies the computer architecture and OS to install to. In truth, the value is no longer a triple but a quintic value.

For WSL / Ubuntu, the host triple is x86_64-unknown-linux-gnu. For Mac, the host triple is x86_64-apple-darwin. The toolchain string consists of the channel prefix, followed by the host triple; the channels are stable, beta and nightly. Thus, the complete toolchain strings for the stable channel are:

WSL / Ubuntu
stable-x86_64-unknown-linux-gnu
Mac
stable-x86_64-apple-darwin

This is how I ran the rustup installer. Notice that I specified the default, option 1 - standard installation because the default values are optimal.

Shell
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
info: downloading installer
Welcome to Rust!
This will download and install the official compiler for the Rust programming language, and its package manager, Cargo.
Rustup metadata and toolchains will be installed into the Rustup home directory, located at:
/home/mslinn/.rustup
This can be modified with the RUSTUP_HOME environment variable.
The Cargo home directory is located at:
/home/mslinn/.cargo
This can be modified with the CARGO_HOME environment variable.
The cargo, rustc, rustup and other commands will be added to Cargo's bin directory, located at:
/home/mslinn/.cargo/bin
This path will then be added to your PATH environment variable by modifying the profile files located at:
/home/mslinn/.profile /home/mslinn/.bashrc
You can uninstall at any time with rustup self uninstall and these changes will be reverted.
Current installation options:
default host triple: x86_64-unknown-linux-gnu default toolchain: stable (default) profile: default modify PATH variable: yes
1) Proceed with standard installation (default - just press enter) 2) Customize installation 3) Cancel installation >
Enter
info: profile set to 'default' info: setting default host triple to x86_64-unknown-linux-gnu info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu' info: latest update on 2024-05-02, rust version 1.78.0 (9b00956e5 2024-04-29) info: downloading component 'cargo' info: downloading component 'clippy' info: downloading component 'rust-docs' 15.1 MiB / 15.1 MiB (100 %) 9.6 MiB/s in 2s ETA: 0s info: downloading component 'rust-mingw' info: downloading component 'rust-std' 24.6 MiB / 24.6 MiB (100 %) 18.3 MiB/s in 1s ETA: 0s info: downloading component 'rustc' 73.8 MiB / 73.8 MiB (100 %) 18.1 MiB/s in 4s ETA: 0s info: downloading component 'rustfmt' info: installing component 'cargo' info: installing component 'clippy' info: installing component 'rust-docs' 15.1 MiB / 15.1 MiB (100 %) 3.6 MiB/s in 3s ETA: 0s info: installing component 'rust-mingw' info: installing component 'rust-std' 24.6 MiB / 24.6 MiB (100 %) 10.9 MiB/s in 2s ETA: 0s info: installing component 'rustc' 73.8 MiB / 73.8 MiB (100 %) 10.8 MiB/s in 7s ETA: 0s info: installing component 'rustfmt' info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'
stable-x86_64-unknown-linux-gnu installed - (rustc does not exist)
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, you need to source the corresponding env file under $HOME/.cargo.
This is usually done by running one of the following (note the leading DOT): . "$HOME/.cargo/env" # For sh/bash/zsh/ash/dash/pdksh source "$HOME/.cargo/env.fish" # For fish

All OSes

The rustup installation program modifies both ~/.bashrc and ~/.profile, which is redundant. The following line was appended to both files. I deleted it from ~/.profile.

Extra line appended to ~/.profile and ~/.bashrc
. "$HOME/.cargo/env"

Now I reloaded the shell:

Shell
$ source ~/.bashrc

When rustup runs, it creates a directory called ~/.rustup/:

Shell
$ tree -d -L 3 ~/.rustup/
/home/mslinn/.rustup/
  ├── downloads
  ├── tmp
  ├── toolchains
  │   └── stable-x86_64-unknown-linux-gnu
  │       ├── bin
  │       ├── etc
  │       ├── lib
  │       ├── libexec
  │       └── share
  └── update-hashes
11 directories

~/.rustup/settings.toml is an important configuration file for Rust:

~/.rustup/settings.toml
default_toolchain = "stable-x86_64-unknown-linux-gnu"
profile = "default"
version = "12"
[overrides]

Hello, World!

“Hello, world!” was the output of the first C program in the seminal book The C Programming Language, written by Brian Kernighan and Dennis Ritchie and published in 1983. This book is often called “the K&R book”.

Here is the program, in all its glory:

hello_world.c
main() {
  printf("Hello, world!");
}

I learned C from the K&R book; the language and its libraries were small and simple, so it could be mastered in only a few weeks.

As my first Rust program, I decided to write a hello_world equivalent program. As you can see, the Rust version looks almost identical to the C version:

hello_world.rs
fn main() {
  println!("Hello, World!");
}

The Rust Programming Language online book is a great place to start learning Rust.

I did not need to write the above Hello, World! Rust program–Cargo always writes this short program when creating a new Rust project! This is what I actually typed to write the program:

Shell
$ cargo new hello_world
Creating binary (application) `hello_world` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 
$ cd hello_world

Now let’s see what cargo generated in the new hello_world directory structure that it created:

Shell
$ tree -a -L 1
.
├── .git
├── .gitignore
├── Cargo.toml
└── src 
$ cat Cargo.toml [package] name = "hello_world" version = "0.1.0" edition = "2021"
[dependencies]

Every Rust project generated by Cargo starts as the Hello, World! program.

Shell
$ cat src/main.rs
fn main() {
    println!("Hello, world!");
} 

Now let’s run the program:

Shell
$ cargo run
Compiling hello_world v0.1.0 (/mnt/c/work/rust/hello_world)
 Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.64s
  Running `target/debug/hello_world`
Hello, world! 

Visual Studio Code

IDEs had not been invented yet when I first learned C. I am very happy that they were, and today my IDE of choice is the F/OSS Visual Studio Code from Microsoft. JetBrains also makes excellent IDEs, and their Rust IDE, RustRover, is free for non-commercial use. I find that JetBrains IDEs generally offer more capable refactoring than Visual Studio Code; however, JetBrains IDEs do not handle WSL as well as Visual Studio Code does.

The Visual Studio Code documentation has a section entitled Rust in Visual Studio Code. It discusses the Rust Analyzer plugin. Read the fine manual. More documentation.

There is not much to say about Visual Studio Code and the Rust Analyzer plugin; they just work as they should.

Videos



* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.