Book Image

Rust Quick Start Guide

By : Daniel Arbuckle
Book Image

Rust Quick Start Guide

By: Daniel Arbuckle

Overview of this book

Rust is an emerging programming language applicable to areas such as embedded programming, network programming, system programming, and web development. This book will take you from the basics of Rust to a point where your code compiles and does what you intend it to do! This book starts with an introduction to Rust and how to get set for programming, including the rustup and cargo tools for managing a Rust installation and development work?ow. Then you'll learn about the fundamentals of structuring a Rust program, such as functions, mutability, data structures, implementing behavior for types, and many more. You will also learn about concepts that Rust handles differently from most other languages. After understanding the Basics of Rust programming, you will learn about the core ideas, such as variable ownership, scope, lifetime, and borrowing. After these key ideas, you will explore making decisions in Rust based on data types by learning about match and if let expressions. After that, you'll work with different data types in Rust, and learn about memory management and smart pointers.
Table of Contents (10 chapters)

Compiling our project

The basic command to compile a Rust program is simple: cargo build.

We need to be in the directory containing Cargo.toml (or any subdirectory of that directory) in order to be able to do this, since that's how the cargo program knows which project to compile. However, we don't need to give it any other information, since everything it needs to know is in the metadata file.

Here, we see the result of building the chapter02 source code:

The warnings are expected and do not prevent the compile from succeeding. If we look at those warnings carefully, we can see that Rust is a lot more helpful with its warnings than many programming languages, giving us hints for improving efficiency and such, rather than just talking about language syntax.

When we build the program, a Cargo.lock file and target directory are created.

Cargo.lock records the exact versions of dependencies that were used to build the project, which makes it much easier to produce repeatable results from different compilations of the same program. It's largely safe to ignore this file, as cargo will usually take care of anything that needs to be done with it.

The Rust community recommends that the Cargo.lock file should be added to your version control system (Git, for example) if your project is a program, but not if your project is a library. That's because a program's Cargo.lock file stores all of the versions that resulted in a successful compile of a complete program, where a library's only encompasses part of the picture, and so can lead to more confusion than help when distributed to others.

The target directory contains all of the build artifacts and intermediate files resulting from the compilation process, as well as the final program file. Storing the intermediate files allows future compiles to process only those files that need to be processed, and so speeds up the compilation process.

Our program itself is in the target/debug/foo file (or target\debug\foo.exe on Windows) and we can navigate to it and run it manually if we want to. However, cargo provides a shortcut: cargo run.

We can use that command from any subdirectory of our project, and it will find and run our program for us.

Additionally, cargo run implies cargo build, meaning that if we've changed the source code since the last time we ran the program, cargo run will recompile the program before running it. That means we can just alternate between making changes to our code and executing it with cargo run to see it in action.

Debug and release builds

You may have noticed that the program was in a directory called target/debug. What's that about? By default, cargo builds our program in debug mode, which is what a programmer normally wants.

That means that the resulting program is instrumented to work with the rust-gdb debugging program so we can examine what is happening in its internals, and to provide useful information in crash dumps and such, as well as skipping the compiler's optimization phase. The optimizations are skipped because they rearrange things in such a way that it makes debugging information almost incomprehensible.

However, sometimes a program doesn't have any more bugs (that we know about) and we're ready to ship it out to others. To construct our final, optimized version of the program, we use cargo build --release.

This will construct the release version of the program, and leave it in target/release/foo. We can copy it from there and package it up for distribution.

Dynamic libraries, software distribution, and Rust

For the most part, Rust avoids using dynamic libraries. Instead, all of the dependencies of a Rust program are linked directly into the executable, and only select operating system libraries are dynamically linked. This makes Rust programs a little larger than you might expect, but a few megabytes are of no concern in the era of gigabytes. In exchange, Rust programs are very portable and immune to dynamically linked library version issues.

That means that, if a Rust program works at all, it's going to work on pretty much any computer running roughly the same operating system and architecture it was compiled for, with no hassles. You can take your release version of a Rust program, zip it up, and email it to someone else with confidence that they will have no problem running it.

This doesn't entirely eliminate external dependencies. If your program is a client, the server it connects to needs to be available, for example. However, it does greatly simplify the whole packaging and distribution process.