The Rust Programming Language


This article aims to provide a first look at the main features of the Rust programming language and its syntax. It is by now means exhaustive or technical, for more information, refer to the rust book.

Ownership & Borrowing

Rust achieves memory safety by a concept, named: “ownership” and “borrowing”.
Every value has an owner:

let margret = Pug::new();

Here “margret” is the owner of the value. When the owner goes out of scope the memory allocated to the variable is dropped automatically. Borrowing then is passing a variable to a different process without that function taking ownership of it and hence the variable not getting dropped when the function ends.
The borrow checker validates whether all rules are upheld (e.g. null pointer, dangling pointers, race conditions).

Move & copy
let s1: String = String:: from("hello");
let s2: String = s1;   // Move (not shallow copy)

Examine the code above and visualise what you would expect s2 to look.
After the second line, s1 will be dropped and only s2 will point to the memory on the heap. Rust does this automatically to ensure memory safety.
To clone a value Rust has the clone function.
For primitive type variables like integers, values can be copied, however.

let x: i32 = 5;
let y: i32 = x;   // Copy
borrowing
fn calculate_length(s: &String) -> usize {
    let length: usize = s.len();
    length
}

The function above will calculate the length of the borrowed string. The string “s” is only borrowed as indicated by the “&” in front of “String”.

variable declaration (let)

let statements are primarily used to introduce a new set of variables into the current scope. By default, every value is immutable and stored in a stack memory with low overhead. Mutable variables or variables with unknown sizes at compile time are stored in heap memory. Note that the variable type doesn’t have to be explicitly stated.

let thing1: i32 = 100;
let thing2 = 200 + thing1;
let mut changing_thing = true;
shadowing

Multiple variables can be defined with the same name, known as shadowing. This doesn’t affect the original variable in any way beyond being unable to directly access it beyond the point of shadowing. It continues to remain in scope, getting dropped only when it falls out of scope. Shadowed variables don’t need to have the same type as the variables shadowing them.

let shadowing_example = true;
let shadowing_example = 123.4;

Source and further reading, link.

Macros

Macros are extensions to the core Rust syntax provided by libraries and are introduced by an identifier followed by an exclamation mark, for example

println!
match

Similar to C’s or java’s switch construct. Further documentation.

match my_number {
    0     => println!("zero"),
    1 | 2 => println!("one or two"),
    3..10 => { println!("three to ten") }
    _     => { println!("something else") }
}
External crate declaration

An extern crate declaration specifies a dependency on an external library (or crate in Rust terms). The dependency is resolved at compile time.

extern crate std;       // equivalent to: extern crate std = "std";
extern crate std as ruststd; // linking to 'std' under another name
USe

use declaration binds names from a specified module to a local name, shortening the path required to refer to the module item. It does not declare linkage dependency with external crates.

use std::num::sin;

fn main() {
    // Equivalent to 'std::num::sin(1.0);'
    sin(1.0);
}
paths

In Rust double colons (::) serve as path separators.

ident::ident

For a full overview of Rust’s operators, see here.

panic

The simplest error-handling mechanic is called panic. It prints an error message, starts unwinding the stack and usually exits the program.

panic!("AAAaaaaa!!!!");
UNWRAP

unwrap() returns a panic when it receives a “None”.

Other intricacies
  • A program starts at the main function.
  • Every rust program is portable to any system with the “libpthread” library.
  • The “unsafe” keyword commands the compiler to put on its blinds and lets you do risky stuff.
  • traits
  • types
  • slices
  • vectors – variable size arrays
  • structs
  • generics
  • clone – make copy of resource.
  • Vectors and Slices (arrays with variable size).