Rust is a fairly new language invented by Mozilla, originally to help them rewrite parts of Firefox to make it faster. What they really wanted to achieve with Rust was concurrency safety, so they could re-implement their browser engine (servo) to take maximum advantage of parallelism while minimising bugs and security issues.
In the saturated world of programming languages, Rust has managed to introduce some quite innovative features not really seen before in the mainstream programming world, and some of these features are now starting to gain more traction in other mature languages and compilers. For example, the C++ Lifetime Profile is a de facto standard that is currently being implemented in Clang and Visual Studio. Compile-time checking of memory and concurrency safety are a logical next step for all non-managed languages, so learning about these principles in Rust now will prepare you for
them in languages you might use professionally today.
Rust is also worth learning because it’s quite a nice modern language. It has functional programming, immutability or mutability, a powerful package manager (cargo) and a great active community. It’s mature enough to write production code in, but still new enough that the language is still evolving.
So let’s have a quick look at what some simple Rust code looks like, shall we? This example is from a small side project that parses CSV data about stars in our galaxy and writes them back out to disk in a binary format that a web front end can then stream into a WebGL graphics renderer as vertex and colour data. The code below shows how you can read a CSV file, iterate over the lines, call utility functions to parse the textual data into other formats, then serialise it out into a binary output file.
let mut rdr = csv::Reader::from_reader(io::stdin());
// ^ Uses the Rust "csv" crate (installed by Rust's "Cargo" package manager)
// The program accepts CSV data from stdin, but it could also read from a file
let mut sector = Sector {
id: 0,
lod_width: 1000.0,
lod_pos: Vec3 {
x: 0.0,
y: 0.0,
z: 0.0
},
stars: Vec::new()
};
// ^ initialise a stellar "Sector". Sector is a C-like struct, but Rust has a nice syntax for easily initialising
// data structures, almost as easy as JSON in JavaScript
let mut locator_id = 100;
// ^ all variables are "immutable" by default in Rust. This is similar to "const" in C languages, but
// more powerful. You must explicitly declare a variable mutable if you want to change it later.
// See https://doc.rust-lang.org/1.8.0/book/mutability.html for more information.
for result in rdr.records() {
let record = result?;
// ^ Rust's iterator syntax is clean and simple
// CSV header:
// id,hip,hd,hr,gl,bf,proper,ra,dec,dist,pmra,pmdec,rv,mag,absmag,spect,ci,17x,y,z,vx,vy,vz,rarad,decrad,pmrarad,pmdecrad,bayer,flam,con,comp,comp_primary,base,lum,var,var_min,var_max
let star_pos = Vec3 {
x: parse_float(record.get(17)),
y: parse_float(record.get(18)),
z: parse_float(record.get(19))
};
// ^ here we parse a Star's cartesian X,Y,Z location in parsecs
let star = Star {
locator_id: locator_id,
frac_pos: abs_to_sector_relative_frac(star_pos, §or),
data: parse_spectral_type(record.get(15)) as i32
}; // ^ the function parse_spectral_type actually returns an i16, but Rust lets us safely upcast using 'as'
sector.stars.push(star);
locator_id += 1;
}
let mut file = File::create("page.file").unwrap();
bincode::serialize_into(&mut file, §or).unwrap();
// ^ once we're done, we use the "bincode" package to apply a simple binary serialization, and write the output
// to "page.file" on disk. Note the "unwrap" calls here: this is part of a very nice feature of Rust related to
// error handling: it allows the compiler to check if you are handling error cases properly, with "unwrap" being
// a sort of "opt out" from this check where you say "it's okay for my program to just crash if this returns an
// error". Rust's powerful pattern matching makes using Options and handling errors quite nice.
// You should read more about it here: https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap
Of course this is a very fast and short dive into Rust. We haven’t even touched on borrow checking or other interesting features yet, but hopefully this has given you a feel for the language and what it’s generally about: safety, performance, and clean, readable code.
Like what you see? Here’s some further reading:
https://doc.rust-lang.org/rust-by-example/
https://www.udemy.com/course/rust-lang (Paid course)