Getting to know Rust

10/21/20 • Carsten Haubold

These are my notes about Rust, updated from time to time while I read through the pretty well written Rust-book.

Variables

  • defined by let x = value are const by default, add mut to make them mutable

  • add a type annotation by a colon before the value if unclear

    let x : u64 = 99999999999999;
    let mut b = 12;
    b = b + 18; // is there a += operator?

Syntax

Very close to Swift, but with semicolons at line ends.

In Rust an "expression" returns a value, and a "statement" is something that doesn't return a value, like a function call without return value, or an assignment (you can't do a = b = c as in C). By adding a semicolon, you can turn an expression into a statement.

The return value of a scope is actually given by the last line in a block. So in a function you don't need a return statement at the end. But you can also do things like this:

let a = {
    let b = 17;
    let c = 999;
    b + c
}; // a = 116

Functions

Defined with the fn keyword.

Memory management aka Ownership

This is probably the feature I like most, because it is so easy to mess it up in C++. In Rust, there is always only a single owner of some instance. Either you pass this ownership around via assignments and function calls (behaves like passing a std::unique_ptr), or you explicitly state that you want to pass a reference, which you have to mark on both sides, the receiver and the sender, with an &.

let a = String::new("Hello world");
let b = a; // this invalidates a! The compiler will not let you use a afterwards!

fn doStuff(s : String&) {
    println!("got string {}", s);
}

doStuff(&b); // hands an (immutable=const) reference into the function

Moreover, everything is const -- or in Rust terms immutable -- by default. If you want to hand a mutable reference around, add mut.

let mut a = String::new("Hello world");

fn doStuff(s : mut String&) {
    println!("got string {}", s);
    s.append("!");
}
doStuff(mut &a); // I like how obvious that makes the ownership / mutability
println(a);

Module system with crates: Cargo

One thing I really like about the more modern languages is that they think about the modularization and deployment steps right from the start. Rust ships with a tool to create projects, to create libraries, and to manage dependencies. That is such a huge benefit compared to C++, where the dependency handling is still a nightmare. 1

Questions:

  • is there a shortcut such as the ? in Swift for the Optional<T>?
  • How do generics/templates work?
  • how does inheritance work, does it exist?
  • Are "Traits" similar to interfaces / protocols?

  1. I know, there's conan.io which can do the trick. Or vcpck. Or you can wrap everything in conda packages to set up a C++ development environment -- which works nicely, I have used the latter extensively. But there you have it already: there is a multitude of options, none are really widely used. And in practice, it's often a company- or homegrown setup.