What Rust Is All About: A Small Tour

In this post, we'll try to give you a taste of Rust's key features so you may get a feel for the language. We'll touch on the type system, some handy functional features, traits, and more!

Introduction#

Rust is a systems programming language that was conceived at Mozilla and is now developed by a larger community. Initially, its purpose was to help rewrite portions of Firefox's codebase (largely C/C++) to improve its safety and security. It has since enjoyed growing adoption in fields such as

  • systems programming,

  • embedded,

  • WebAssembly,

  • blockchain,

  • web servers,

  • networking, and

  • command-line utilities.

Rust is a statically typed language that emphasizes static code analysis, helpful compilation errors, convenient and comprehensive tooling, memory and concurrency safety, sheer performance, and abstractions that incur no (or little) runtime cost. Its memory model avoids the overhead of a garbage collector, but at the same time, the language's compiler enforces a set of rules that effectively prevent memory errors common in C/C++ applications.

What you will learn#

This is not a comprehensive "learn Rust in one hour" guide. It should, however, give you a little taste of what the language is about and help you decide if it's for you! We will guide you through some of the key concepts you'll inevitably stumble into in Rust code, including custom types, error handling, ownership, closures, higher-order functions, iterators, pattern matching, and traits.

Prerequisites#

This guide is intended for people with some prior high-level programming experience, though which particular language(s) you've previously worked with shouldn't overly matter.

If you'd like to give the snippets a run, the easiest way is to use the Rust Playground online. If you prefer to run things locally, the Getting Started chapter from the Book will help you get your environment and a "Hello, World" project set up!

Safety and Reliability#

Extensive Type system#

A comprehensive static type system means safer code and fewer manual tests that need to be written. The more information you can encode in the type system, the more Rust can check for free during compilation, allowing greater confidence in the correctness and reliability of your programs!

Rust has structs. Structs have fields.

Rust also has enums for when a thing can be either this or that. Enums have variants. An enum value can only be set to one variant.

Enum variants can hold data.

Both structs and enums can be generic and accept arbitrary concrete types inside. This is possible by declaring type variables in angle brackets (<>).

In the example above, the compiler will deduce that foo is of type Wrapper<f64>. Wrapper<T> is not a dynamic type! It's resolved during compilation.

Oh, and by the way, the let statement is how you declare a local variable. It accepts type annotations, but most of the time they're not necessary - Rust might be a disciplined and strongly-typed language, but it's fairly smart and able to infer types itself a lot of the time.

You can add methods to any type you define using impl blocks.

println! allows us to print stuff to the terminal. The {} token allows us to insert some dynamic values, in this case, self.x and self.y.

Error handling made simple#

Rust doesn't have anything like a try...catch statement. Instead, there is the Result<T, E> type, defined more or less like so:

Two types should be provided here. T is the type of the actual return value. E is the type of error data.

A function that may fail should return a Result - like the one below that attempts to sum a vector, but fails if it's empty.

The unit type () is often used to signify nothing is returned. In this case, we're basically saying we don't want to add any extra error information if the function fails - we just want to know that it failed. In "real" Rust code, it's generally a good idea to provide an error type that implements the std::error::Error trait, but that's outside of our scope right now.

If we want to use our my_sum function now, we cannot ignore the fact it might produce an error. The snippet below won't work.