"Is Rust a great fit for this project?" I get this question quite frequently so I think it's time to write down my thoughts if it can avoid you some painful and costly mistakes. Short answer: no. Coming from someone who wrote a successful book about Rust (Black Hat Rust)
And don’t get me wrong, I think Go is ok and I use it from time to time. When Go and Rust started to get traction, I actually laughed at Rust thinking it was a stupid language. Why would anyone use Rust when you had Go, it sounded so great with its go routines and all. I then started to use it, and it wasn’t bad, but it wasn’t something that got me all excited either. And it was the horrible error handling and all these simplifications that sacrifices correctness that made me feel it was only an ok language. It is the correctness of Rust and that you have to handle all errors aso, that makes it a bit annoying, but it is also these things that makes it great.
I learnt go first, and used it in production for years. I loved it at first. It made a lot of promises that I agreed with and it wa easy to learn. But over the years it fell short time and time again.i kept getting issues in production like forgetting to close a file handle ending up eating all resources or random panics from null pointers.
Then I started learning rust. It was not easy to do, I think I have up a couple of times before I really got it. But the more I learn it the more I love it. The promises it made have held up far better than gos and quite often now when I find an issue in some go I have written I realise that it would not even be possible in rust to encounter.
Rust makes sure the things you write are more correct so you spend more time upfront and avoid time spent sweating over issues in production and trying to figure out why something has now fallen over in the dead of night when you just want to be sleeping.
Depending on how your logical flow works, this can end up causing bugs in a very surprising and hard to detect way.
Also, you can call methods on nil values, like this:
type A int
func (a *A) doStuff() {
*a = 3
}
var a *A = nil
a.doStuff()
This panics inside doStuff, not at the call site, which can mean functions could run fine and fail later, making it harder to track down the nil value.
There’s a lot of other footguns, especially as you get into multithreading. I started building code with Go back at 1.0, and they didn’t turn on multithreading by default until 1.4 or 1.5 (I forget which), at which point our assumption that the built-in map type was multithreading-safe didn’t hold (at least for assignments and reads). That was in the documentation, but the fact that it worked fine for multiple releases made it that much worse.
I still think Go is a fine language, but it should be limited to smaller scale projects like microservices because there are enough gotchas that the simplicity of the language hides for me to not recommend it.
And don’t get me wrong, I think Go is ok and I use it from time to time. When Go and Rust started to get traction, I actually laughed at Rust thinking it was a stupid language. Why would anyone use Rust when you had Go, it sounded so great with its go routines and all. I then started to use it, and it wasn’t bad, but it wasn’t something that got me all excited either. And it was the horrible error handling and all these simplifications that sacrifices correctness that made me feel it was only an ok language. It is the correctness of Rust and that you have to handle all errors aso, that makes it a bit annoying, but it is also these things that makes it great.
I learnt go first, and used it in production for years. I loved it at first. It made a lot of promises that I agreed with and it wa easy to learn. But over the years it fell short time and time again.i kept getting issues in production like forgetting to close a file handle ending up eating all resources or random panics from null pointers.
Then I started learning rust. It was not easy to do, I think I have up a couple of times before I really got it. But the more I learn it the more I love it. The promises it made have held up far better than gos and quite often now when I find an issue in some go I have written I realise that it would not even be possible in rust to encounter.
Rust makes sure the things you write are more correct so you spend more time upfront and avoid time spent sweating over issues in production and trying to figure out why something has now fallen over in the dead of night when you just want to be sleeping.
I don’t mind the error handling in Go, what bothers me is a bunch of safety issues. For example:
Depending on how your logical flow works, this can end up causing bugs in a very surprising and hard to detect way.
Also, you can call methods on nil values, like this:
This panics inside doStuff, not at the call site, which can mean functions could run fine and fail later, making it harder to track down the nil value.
There’s a lot of other footguns, especially as you get into multithreading. I started building code with Go back at 1.0, and they didn’t turn on multithreading by default until 1.4 or 1.5 (I forget which), at which point our assumption that the built-in
map
type was multithreading-safe didn’t hold (at least for assignments and reads). That was in the documentation, but the fact that it worked fine for multiple releases made it that much worse.I still think Go is a fine language, but it should be limited to smaller scale projects like microservices because there are enough gotchas that the simplicity of the language hides for me to not recommend it.