- Rust is strongest where you need high performance, low latency, or low memory usage. If you're spinning up 20 machines to run a single data-crunching job, or if you care about your 99th percentile tail latency, Rust is great. This is where Rust shines compared to GCed languages.
- Rust also shines where programs need to transform large, complex data structures correctly. It's fantastic for anything resembling a compiler, even if the output isn't executable code. This is where Rust shines compared to languages without Rust's fancy "enum" and "match" (aka union types) and without Rust's strict null handling.
- Rust is strongest for CLI tools and for microservices with a small API.
- Rust is weakest for rapidly-changing business logic. This is because most companies have few Rust programmers, but they have many people familiar with scripting languages. In these circumstances, putting the business logic in a typed scripting language will make it accessible to more developers, and easier to change.
- Rust's closest competitor is C++. Rust has better tooling out of the box, it's arguably easier to master, and it has many fewer ways to shoot yourself in the foot. But in many problem domains, including games and native desktop GUIs, C++ will have far more mature libraries.
In my experience, the best way to introduce Rust to a company is to pick a project which is exceptionally well-suited to Rust's strengths, ask for permission to build a prototype in Rust, and do a really compelling job.
- A dramatic reduction in runtime crashes, and a ~70% reduction in security vulnerabilities (based on Microsoft's analysis of security bugs, but also personal fuzz-testing experience).
- Much better out-of-the-box tooling. You can set up cargo, VS Code and rust-analyzer in 5 minutes. "Maintaining the build system" will typically become a thing of the past. Rust also provides many verification features for free that would require setting up static analyzers for C++.
- A much easier time integrating third-party libraries. But you may loose access to certain domain-specific libraries, depending on your problem domain.
- Safer use of complex threading and/or async, if you need them for performance. Look at the Mozilla experience converting complex concurrent C++ modules to Rust. They've written a lot about it and it has almost always been a giant win.
- Hiring is a tradeoff: Depending on where your company is located, you may have more local C++ programmers. But if you do remote hiring, the Rust talent pool can be fantastic.
- It's easier to train people from scratch. Rust is not a small language, but it's a lot smaller than knowing the entire history of C++ gotchas and idioms. Also, Rust provides much better guardrails for novice Rust developers. It's feasible to take a strong junior developer, train 'em up, and turn 'em loose.
A migration like the one you describe makes the most sense if 3 things are true:
1. Your C++ codebase is small enough to incrementally rewrite (and your team knows how to manage an incremental rewrite without too much loss of velocity).
2. Your problem domain does not rely on major C++ libraries with no Rust equivalents.
3. Your developers are enthusiastic about Rust.
If any of those three factors were missing, however, then I would normally advise against a rewrite.
I haven't worked on any bigger production projects in Rust, so how to say if it would be a common experience, but sounds interesting
If the contender language is Go, think carefully before using Rust.
If the contender language is Python, think very carefully before using Rust.
Rust does an excellent job of providing fairly comprehensive opt-out safety, compared to C++'s hodgepodge of incomplete, edge case laden, compiler and tool specific, opt-in static analysis and annotations. Even a C++ skeptic like myself can learn a lot about how terrible the language is, by trying to write the same code in Rust and learning exactly why the borrow checker is complaining.
But it's also a very front-loaded knowledge bomb, with a nasty learning curve. It took me a good month or two to stop fighting the borrow checker and embrace clones and RefCells. Perhaps a less painful learning curve than debugging C++ gone wrong, but certainly more painful than a lot of other non-systems languages - I doubt it'd make a good 1st programming language. Arrogance means you'll shoot yourself in the foot with `unsafe { ... }` escape hatches as well, and end up debugging memory issues anyways. Web and gamedev ecosystems are still weak for my tastes, although improving. I want a nice existing successful fun game to contribute to, that's written in Rust, so I don't have to find the motivation to RIIR an existing one or write my own.
Also little point in statically proving to the compiler that your code is totally fine and safe if your bugs are already shallow through testing. I feel little desire to rewrite a typical C# codebase in Rust - what the borrow checker can catch, so too can proper unit tests, for the most part. Maybe invest in some code coverage analysis for CI instead. Unless those GC pauses are actually causing problems... or you have enough data races from missing mutexes in your multithreading code...
- infra projects.
- Resource constrained environment (depends on the hardware)
- Command line program
- WebAssembly for a complicated webapp (like Figma)
- Anywhere security is a concern
Whereas a web service that reads from a database and supports some CRUD operations? Many languages specialise in this problem. If the business domain is complicated and needs a good type system to express that domain - yeah maybe Rust is a good fit. But you're probably better off with Python or Ruby or Go. I could revisit this opinion in a couple of years if the Rust ergonomics initiatives succeed.
Video games - it's very early days for Rust. There's a lot of ongoing work (like Bevy) that could bear fruit in a couple of years but C++ is much better today.