I’ve been getting started learning the Rust language, and thought I’d share some my initial take-aways.

I’m an embedded developer, and most of the code I write for work is in C. As I’ve mentioned before, I’m particularly interested in Rust as it’s a systems language that might one day be a suitable replacement for C/C++ in my everyday work.

Getting Packages to Build

Of course the first order of business is figuring how to build Rust projects. For simple things you can use rustc directly, but most Rust projects use Cargo, Rust’s package manager. Cargo seems to work pretty well, especially for a language that’s explicitly not ready for prime time yet. There are comparable in-production languages that don’t fare so well.

I did have some issues when building some packages that linked against C libraries. It had trouble finding the C libraries. I’m running OSX, and I have the necessary libraries built with homebrew and linked into /usr/local/lib , and I even have pkg-config setup properly, and it still couldn’t find them. It would fail with something like:

cargo build error: linking with `cc` failed: exit code: 1 note: cc '-m64' '-L' '/usr/local/lib/rustlib/x86_64-apple-darwin/lib' '-o' 'rust_2d_physics' 'rust_2d_physics.o' '-Wl,-force_load,/usr/local/lib/rustlib/x86_64-apple-darwin/lib/libmorestack.a' '-nodefaultlibs' '-fno-lto' '-Wl,-dead_strip' '-lcsfml-system' '-lcsfml-window' '-lcsfml-audio' '-lcsfml-graphics' '-lcsfml-network' '-lSystem' '-lpthread' '-lc' '-lm' '-lcompiler-rt' ld: library not found for -lcsfml-system clang: error: linker command failed with exit code 1 (use -v to see invocation) error: aborting due to previous error Could not compile `rust_2d_physics`. cargo build error: linking with `cc` failed: exit code: 1 note: cc '-m64' '-L' '/usr/local/lib/rustlib/x86_64-apple-darwin/lib' '-o' 'rust_2d_physics' 'rust_2d_physics.o' '-Wl,-force_load,/usr/local/lib/rustlib/x86_64-apple-darwin/lib/libmorestack.a' '-nodefaultlibs' '-fno-lto' '-Wl,-dead_strip' '-lcsfml-system' '-lcsfml-window' '-lcsfml-audio' '-lcsfml-graphics' '-lcsfml-network' '-lSystem' '-lpthread' '-lc' '-lm' '-lcompiler-rt' ld: library not found for -lcsfml-system clang: error: linker command failed with exit code 1 (use -v to see invocation) error: aborting due to previous error Could not compile `rust_2d_physics`.

There didn’t seem to be a way to directly tell cargo where it should look for C libraries. However I was able to get it to work by setting the LIBRARY_PATH environment variable:

LIBRARY_PATH=/usr/local/lib cargo build

Rust Changes Fast

Like, ridiculously fast.

I upgraded to the latest Rust nightly build twice in a two week period and had either my own code, or packages I depended on break both times. This is by far the biggest reason you shouldn’t use Rust for a production project yet.

However, they are hoping to have a 1.0 beta release by the end of this year (2014), so we might start seeing some stability soon.

Also, the standard libraries seemed well documented and fairly mature, especially for a brand new language.

Rust’s Awesome (Frustrating) Safety

The biggest selling point for Rust for me is that it’s a safe systems language. Which means I manage memory by myself and can play around with references and pointers, but that I’m guaranteed the absence of segfaults, deadlocks, memory leaks, and all sorts of other terrible things.

There is one key rule that rust enforces to enable much of this safety: You are only allowed a single mutable reference to a given object at a time. Most of the time, this isn’t an issue. But sometimes you have to rethink how you approach a problem. For example, something like this is not allowed in Rust:

for a in things . iter_mut ( ) . by_ref ( ) { for b in things . iter_mut ( ) . by_ref ( ) { mutate_a_and_b ( a, b ) } } for a in things.iter_mut().by_ref() { for b in things.iter_mut().by_ref() { mutate_a_and_b(a, b) } }

This isn’t allowed because a and b are both mutable references that will sometimes reference the same object. However sometimes you can get away with this instead:

while let Some ( a ) = things . mut_shift_ref ( ) { for b in things . iter_mut ( ) . by_ref ( ) { mutate_a_and_b ( a, b ) } } while let Some(a) = things.mut_shift_ref() { for b in things.iter_mut().by_ref() { mutate_a_and_b(a, b) } }

This block of code is valid since a and b can never point to the same thing.

Getting Started with Rust

If you want to try Rust out yourself, there is some good info for getting started here.

Since The language is both new and changing rapidly Google/Stackoverflow isn’t as effective as you might be used to. I highly recommend asking questions on the Rust IRC channel. The people there are very nice and helpful. Also, the documentation is both helpful and has a pretty nice interface.