Go and Rust are some
relatively new languages not that widely used languages that compile down to native code for a platform. That’s a difference to languages like Java / Kotlin that run on a JVM and use a middle layer called bytecode that then gets executed on the host platform.
I am a big fan of the JVM. It’s fast and has a stable and rich ecosystem. Besides, Java, Kotlin and Scala are really cool languages. But the JVM slows down the initial application startup. Why? Because first the JVM has to start, then the application. The JVM startup delay might not be a problem for you - but sometimes - especially when you start / stop your web containers often (Lambdas, Kubernetes) - it becomes a problem because the first request to the newly started container is simply slow.
For Go and Rust it is different - they compile down to native code and start right away.
Unfortunately, I did not yet have the time to use either Go or Rust in a larger project - my knowledge is just from some experiments with the languages. So take this with a grain of salt - and if you know things better - let me know!
- Not many language features - easy to learn. Yes - and it finally got generics.
- No semicolons (I got used to that).
- Built-in mechanism to distribute load to multiple cores via gochannels / goroutines.
- Executables are self-contained and ready to run - compilation for other platforms is straightforward.
- Formatter is built-in. All go programs look roughly the same (tabs won).
- Compilation is very fast.
- The standard library has a huge amount of cool stuff readily available. Http server, html templating, json parsing - it’s all there with zero dependencies. I really like that!
- First class support for tests.
- Very simple way to allocate and de-allocate memory - it’s done by the language and a garbage collector.
- Go is a procedural language. If you like a functional approach with immutability then Go might not be right for you. Mutability is embraced all over the place. And that is not an issue as e.g. goroutines make it simpler to run things in parallel when using mutable variables.
- While gochannels are cool and a language-level feature - they are not preventing all errors - and you might shoot yourself in the foot when using them.
- I got used to some language-level features like advanced pattern matching - this can be simulated somehow in Go, but it doesn’t look nice.
- Error-handling is a bit clunky, but in general it looks no worse or better than traditional try-catch concepts.
- The garbage collector might be an issue for certain (rare) application loads.
A great way to learn Go is quii’s course Test driven development with Go. I really think that TDD is a supreme way to learn new languages.
- Potentially as fast as C (or faster). Does not have a garbage collector. Uses the concept of ownership and borrowing. These concepts are strange at first but allow the language to “automatically” malloc / free memory from the heap. Clever.
- Optional type built-in.
- Pattern matching built-in
- Immutability is a first class citizen.
- Very helpful compiler messages.
- Very cool feature: Documentation with code samples is being treated as a test and automatically compiled and tested to make sure it stays up-to-date.
- First class support for tests
- Well. Ownership, borrowing and referencing is a new concept and you have to get used to it. It basically means: Use a variable only once. You can work around it, but learning that is key to understanding Rust - and no other language has that concept.
- Tests usually live in the same files as the code. I have to get used to that to be honest. You can use separate files, but the Rust community seems to endorse this approach.
- Especially when compared to Go Rust is much much more complex. You’ll have to learn a lot to start.
- It has semicolons. In 2022 (ok that one is tiny).
- Cargo and ecosystem are more complex.
- Formatting not enabled by default.
- The compiler seems to be slower (even in draft mode) than Go’s.
The biggest differentiator between the languages to me is how memory on the heap is allocated and deallocated. Go uses a garbage collector - Rust the concept of ownership / borrowing.
If you really want to work on high performance applications - then Rust might be “faster” for some edge cases. Discord changed from Go to Rust because the garbage collection killed their performance. And Rust’s “limitations” might lead to faster code by default.
But don’t take this too lightly - Both languages are highly recommended for even the most performance-demanding workloads.
I also really like Go’s approach to be a simple, but fully featured language. Everything you need is built-in. And Go is a lot easier to learn than Rust. One thing that contributes to that is the garbage collector - it makes allocation / deallocation a no-brainer for the user.
A last look at the Stack Overflow developer survey reveals that Go and Rust are roughly on the same level . Go is a bit more widely used than Rust. But both languages are way less used than “competitors” like C / C++ or Java.
If I’d have to choose between these two I’d be - first of all - sad because both languages are awesome. Then I’d choose Rust because I feel that the concept of ownership is too powerful not to use, and (except for the semicolons) the language resembles much more more my current way of writing code (immutability, Optionals etc). But Go is still really cool. It’s a hard choice.
- Image by Matt Artz