Orienting to Programming with Rust

This blog post intends to provide guidance that may assist developers familiar with common web programming technologies such as ASP.NET and JavaScript to learn the rust programming language. I am going to try to list the little things that I had to learn before I could do anything correctly with rust. This post does not explain how to use rust but lists key concepts including significant differences from other languages.

I need to explain that I am not a professional programmer, and I am just learning rust. My background is more with C#, as I have learned to avoid the risks of C (depending on perspective and preference) compounded by the incredible complexity of C++ and the (compared to .NET) relatively ridiculous development environments and toolchains for both. I certainly prefer Rust to either of those languages.

I also need to be clear that I do not know rust terminology. I understand some of the concepts, but I might use the wrong terms. Maybe it doesn’t matter; the compiler cares about our symbols, not what we call them. For me, it’s more important to use terms that convey my meaning.

It seems like everyone using rust is supposed to read the same book and program the same way. The rustfmt command reformats *overwrites* our code files, generally adjusting whitespace and other aspects without changing any tokens. The cargo-clippy command provides a variety of suggestions for modifying code to meet rust conventions. The community, which generally seems to come from a C/C++/Linux background, strongly encourages use of those conventions. Though in some cases it seems almost unavoidable, working against these conventions is working against ourselves and everyone else in the community. To maximize productivity in rust, we must understand and follow the conventions whenever possible rather than trying to apply coding styles from other platforms to rust.

In terms of coding symbols, general code structure, and in some cases exact or almost-exact syntax duplication, rust appears much like other languages that eventually derive from things like C. Assumptions based on this similarity can lead to confusion. It is relatively easy to get the rust compiler to accept code without understanding exactly how that code functions.

There are a few significant rust constructs to understand. Maybe the key is enums. In other languages, enums may be simple things, like hard-coded lists of values. In rust, an enum is still simple and part of a static list of values, but those values can contain other values.

Enums are not the same concept in rust. They can contain things. Honestly, we need to understand how enums work before we do any coding with rust.

It seems like the main way to create custom data types is with structs, which can have methods that can be members, so they’re somewhat like classes with both static and member methods in C#.

It seems strange, but once we get past some of the confusion, we embrace these things, even the conventions that may be completely dissimilar to our own.

Rust does not have a garbage collection. Resources free when they go out of scope. We do not need to allocate memory manually – we can simply declare things – but we need to be aware of the impact of this approach to memory management. Sometimes the compiler knows things about potential resource lifetime limitations that we may not have considered; sometimes we know things about resource lifetimes that the compiler does not. Sometimes we can tell the compiler about those things; sometimes we need to change our approach to satisfy the compiler.

For performance, we prefer to allocate things on the stack rather than the heap, although the heap may be faster for large data structures and other cases. While the relative performance impact often seems almost theoretical, it is important to understand the difference. The first thing to understand is ownership and then probably lifetimes.

Because other languages can provide such a relatively high level of abstraction, working with strings in rust can be challenging, confusing, and even frustrating at first, but are actually a good way to learn about ownership and lifetimes. It is important to understand the difference between the owned String type (I think generally on the heap, works like a reference in other languages) and str slices (I think generally on the stack). Rust has a few other string types that are less important to understand.

Beware that rust seems to like to keep all types for a path/scope/namespace in a single source code file. Working against this presents some challenges that involve the module system. For relatively small programs, we can use rust without much understanding of its crate and module system. When we want to start separating our programs into multiple files, we need to understand how packages, crates, and modules work, especially how they correspond to files and paths (namespaces). Otherwise, our expectations based on things like namespaces may lead us in the wrong directions.

We can do relatively simple things with just an .rs source code file and the rust compiler on the command line, but really you should start with cargo, which is developer tooling that comes with rust itself. I have found Microsoft Visual Studio Code to be an excellent development environment for working with rust.

The ! token does not always mean not. At the end of what looks like a function/method name, it means macro. Any rust program likely uses macros constantly but I have not even read about what they are.

It seems that there is no ++ operator to increment an integer by one. This is a minor inconvenience that is highly worthwhile just to offend C++ programmers.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: