Rust Sucks If I Fail To Write X
A recurring theme of critique against the Rust
language is “You cannot write basic data structures without resorting to
unsafe
”.
First, let me tell you that this is mostly true. While you can hack together a
“list” that will be backed by a Vec
of nodes with indices to the next /
previous item, this approach is quite wasteful – and gains little compared to
using the Vec
directly.
As an aside, remember that the only difference to C/c++ is that if you write a “basic linked list” in them, all of your code will be unsafe. And those seemingly simple structures are actually surprisingly tricky to get right. Try to write a doubly linked list without getting a segfault at least once. I’ll wait. Even if you manage to do it safely, it will usually still be inferior in terms of performance (unless you do a lot of insertion/removal at various places).
Rustaceans usually opt for continuous data layout (known in C/C++ lingua as
array-of-struct or struct-of-array depending on priorities), which is more
cache-friendly than reference-heavy data structures anyway. For the remaining
scenarios, there are crates for finite state transducers, specialized
hashmaps and graphs – each a simple cargo add
away (ok, once you’ve done
cargo install cargo-edit
). Rust’s facilities for code reuse makes using them
a no-brainer.
Even so, there is more decorum around using those data structures, especially when borrowing into them (which is one of the selling points of Rust after all), but on the other hand, this steers programmers in the direction of keeping layout easy, which makes for maintainable and often surprisingly fast programs. Indeed anectotical evidence shows that “unoptimized” (read: The first version someone got to work) programs perform within an order of magnitude to optimized C code, while being – at least to the trained eye – vastly easier to read.
In addition, Rust is balanced so that it’s possible to reason locally (within a function) about control- and data flow. This gives Rust code a certain obviousness that leaves little room for errors. Note however that some Rustaceans use the abstractive power of Rust to write fairly “lofty” code that over-generalizes and as a result isn’t as easy to read or reason about. Rustaceans being bullish on documentation at least partially remedies this problem.
So, to summarize my rambling above:
-
Should you write data structures in Rust? If you just want to use them, get one of those available in
std
or on crates.io. Otherwise, knock yourself out; if you don’t, the borrow checker likely will. -
Is this a problem with Rust? Not at all. You can do a lot of stuff just using the supplied types. And you can always reach for
unsafe
if you really need.