Rust is a system programming language developed by Mozilla, whose version 1.0 appeared in 2015. A system language means that you have control over the memory used by the program—you decide whether you want to allocate the memory on the stack or the heap, and when the memory is freed. But don't worry; in Rust, the compiler is very helpful and prevents you from making the many mistakes you can make in C and C++ that lead to segmentation faults. A segmentation fault arises when the programmer tries to access some memory that is not accessible to its process. Memory unsafety leads to bugs and security flaws.
Moreover, the compiler is smart enough to know where to insert the memory deallocation instructions so that you don't need to manually free your memory, all of that without a garbage collector, which is one of its greatest features. Since Rust is safe and fast, it is the perfect candidate for writing operating systems, embedded programs, servers, and games, but you can also use it to develop desktop applications and websites. A great example of this power is the Servo web engine, also developed by Mozilla.
Rust is multi-paradigm: it can be used in an imperative or functional way and you can even write concurrent applications safely. It is statically typed, meaning that every type must be known at compile time, but since it uses type inference, we can omit the type for most local variables. It is also strongly typed, which means that its type system prevents the programmer from some kinds of errors, such as using the wrong type for a function parameter. And Rust is very good at writing concurrent software because it prevents data races, which is concurrent access to a variable where one is a write; this is an undefined behavior in other languages. One thing to remember when reading this book is that Rust prevents you from shooting yourself in the foot. For instance, Rust doesn't have:
- null pointers
- data races
- use after free
- use before initialization
- goto
- automatic coercion of Boolean, numbers and enumerations
Also, Rust helps to prevent memory leaks. However, all of this is possible with unsafe
code, which is explained in Chapter 3, Events and Basic Game Mechanisms.
Without further ado, let's install the tools we'll need throughout the book.
In this section we'll install rustup
, which allows us to install different versions of the compiler and package manager.
Go to https://rustup.rs and follow the instructions in order to download rustup-init.exe
, then run it.
Unless your distribution provides a package for rustup
, you'll need to install rustup
by typing the following command in your terminal:
$ curl https://sh.rustup.rs -sSf | sh
info: downloading installer
Welcome to Rust!
[...]
Current installation options:
default host triple: x86_64-unknown-linux-gnu
default toolchain: stable
modify PATH variable: yes
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
This downloaded rustup
and asked you whether you want to customize the installation. Unless you have particular needs, you'll be okay with the default.
Note
Note
: The $
represents your shell prompt and should not be typed; you must type the text following it. Also, a line of text that doesn't start with $
represents the text output of the program.
To proceed with the installation, enter 1
and press Enter. This will install the rustc
compiler, and the cargo
package manager, among other things:
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2017-07-20, rust version 1.19.0 (0ade33941 2017-07-17)
info: downloading component 'rustc'
[...]
stable installed - rustc 1.19.0 (0ade33941 2017-07-17)
Rust is installed now. Great!
To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH
environment variable. Next time you log in this will be done automatically.
To configure your current shell run source $HOME/.cargo/env
As pointed out by the installer, you need to execute the following command in order to add the directory containing these tools in your PATH
:
$ source $HOME/.cargo/env
# Which is the same as executing the following:
$ export PATH="$HOME/.cargo/bin:$PATH"
(This is only needed once because the rustup installer added it to your ~/.profile
file.)
Now, test that you have both cargo
and rustc
, as you'll need them very soon:
$ cargo -V
cargo 0.23.0 (61fa02415 2017-11-22)
$ rustc -V
rustc 1.22.1 (05e2e1c41 2017-11-22)
Cargo is Rust's package manager and build tool: it allows you to compile and run your projects, as well as managing their dependencies.
At the time of writing this book, the stable Rust version was 1.22.0.
Let's try to build a Rust program. First, create a new project with cargo
:
$ cargo new --bin hello_world
Created binary (application) `hello_world` project
The --bin
flag indicates that we want to create an executable project, as opposed to a library (which is the default without this flag). In the Rust world, a crate is a package of libraries and/or executable binaries.
This created a hello_world
directory containing the following files and directory:
$ tree hello_world/
hello_world/
├── Cargo.toml
└── src
└── main.rs
1 directory, 2 files
The Cargo.toml
file is where the metadata (name, version, and so on) of your project resides, as well as its dependencies. The source files of your project are in the src
directory. It's now time to run this project:
$ cd hello_world/
$ cargo run
Compiling hello_world v0.1.0 (file:///home/packtpub/projects/hello_world)
Finished dev [unoptimized + debuginfo] target(s) in 0.39 secs
Running `target/debug/hello_world`
Hello, world!
The first three lines printed after cargo run
are lines printed by cargo
indicating what it did: it compiled the project and ran it. The last line, Hello, world!
, is the line printed by our project. As you can see, cargo
generates a Rust file that prints text to stdout
(standard output):
$ cat src/main.rs
fn main() {
println!("Hello, world!");
}
If you only want to compile the project without running it, type the following instead:
$ cargo build
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
This time, we didn't see Compiling hello_world
because cargo
did not see any changes to the project's files, thus, there's no need to compile again.