According to the Stack Overflow Development Survey 2021, both Rust and Go (known also as Golang) have a special place in developers' hearts. According to the survey, these programming languages are loved by almost 87% and 63% of the respondents, respectively. This score puts Rust at the top of the list. However, does Rust deserve to be the developers' blue-eyed boy?
In this article, I will compare these two popular solutions, covering aspects like memory management, concurrency, tools, performance, learnability, and more – to give a big picture view of Rust and Go.
Before we touch more deeply on each language’s features, I would like to cover some basic information about Rust and Go to make the article easy to follow.
Rust was established initially by Graydon Hoare at Mozilla Research, but now it stands alone. This open-source project is often shown as a solution to problems C/C++ developers have been struggling with for a long time – memory errors and concurrent programming.
Rust is often mentioned in connection with projects related to embedded devices, kernel driver development, browser engines, and game engines.
- statically typed,
- high-level (but can go down to the bare metal and handle low-level tasks),
- supporting safe concurrency,
- created for achieving a high performance level.
The Go programming language is an open-source solution invented by Google developers Robert Griesemer, Rob Pike, and Ken Thompson.
Golang mixes features of statically-typed and dynamically-typed languages. In terms of its high performance and type safety, it is similar to statically-typed languages and Golang's conciseness, expressiveness, and good readability level are close to dynamically-typed languages.
The Go programming language is described as:
- statically typed,
- with built-in support for concurrent processing.
Are you wondering if Golang may be a good choice for your project? Read our previous article to get the answer.
This is only a quick summary of Go. Read what else you should know about Golang.
Before a detailed comparison of the features of these two programming languages, it is worth mentioning that both Rust and Golang are great, widely-recommended technologies. Some sources may point out only one suitable candidate that should be chosen for every kind of project. However, this is not the right way of thinking – every programming language was created and adjusted for different tasks and challenges. So, the language has to meet the project needs and requirements, not the other way round.
A good knowledge of language features helps with choosing the technology for the project wisely and simply getting the most out of them.
In Rust, the developer has complete control of memory management. We can clearly see in the code when data is freed. Memory management in Rust is known at compile time.
On the other hand, Golang uses the garbage collector concept. Data is not freed immediately. Instead, a background process releases data when the allocated data amount reaches a specified value. Golang’s garbage collector is well optimized, but it is less predictable than Rust memory management and adds overhead.
While writing software in Golang, we have to keep in mind that the garbage collector runs periodically. In many cases developers don’t have to worry about it, but when our service needs to be updated at a rate of tens of thousands per second, Rust might be a better solution. Because of that, Discord is switching from Golang to Rust. Check out other reasons why Discord is switching from Go to Rust.
Memory safety prevents software bugs and security vulnerabilities when dealing with memory access.
Rust and Golang are safe in terms of dangling pointers and use-after-free. Both of them also limit memory leak issues. Each language resolves these problems in a different way. Golang uses a garbage collector. Rust introduced an innovative feature called ownership and borrowing. This is a concept where every object has an owner who can give it to someone else or borrow it. Furthermore, in Rust we can create a ONE AND ONLY mutable reference or multiple immutable references. With this approach, Rust resolves common memory errors without a garbage collector, which makes Rust’s performance higher than that of Golang.
Another problem that programs are vulnerable to is a data race – Rust is safe in this sense because this is undefined behavior that the Rust compiler won’t accept. Golang, on the other hand, is not memory safe when we talk about writing and reading the same variable simultaneously, but Golang resolves this problem using message passing. You will find more about this in the next section.
How does Rust work compared to C? Here, you can check how their safety and performance levels compare in low-level network programming.
Communication between independent threads in most programming languages is made by sharing memory. This imposes more responsibility on developers. Every thread that uses shared memory has to be correctly synchronized. It’s easy to make mistakes at some point.
Do not communicate by sharing memory; instead, share memory by communicating.
This idea is known in both Golang and Rust. Instead of sharing memory, we want to exchange data between threads with message passing. In both languages, it is achievable by using channels. This approach creates explicit places where the data is exchanged, threads use these and the concurrency is less error prone.
To make concurrency easier Golang introduces goroutines. You can think about goroutines as lightweight threads. These are objects managed by Go’s run-time which are scheduled over OS threads. Goroutines are cheap to create and the stack can be resized over time. That's why we can create thousands of goroutines in comparison to OS threads, which are much more expensive.
The downside of this solution is that it adds memory and CPU overhead. Rust wants to avoid even small overheads, so we don’t find this feature in Rust. Choosing between these approaches depends on what we want to achieve.
Both programming languages handle errors in a similar way. In Golang, multiple values from the functions are returned along with the error. Rust introduces the dedicated type, the enum, with two variants: result type and error type. It can be unwrapped with '?', making error handling less verbose than in Golang.
There is no clear answer to which of them is better in this respect – everything depends on individual preferences. Nevertheless, in both approaches, error handling is much more explicit and cleaner in comparison to, for example C++ exceptions.
Thanks to these approaches, it is much more manageable to find functions where an error is not handled and the writing code is much easier and safer.
It takes a few hours to learn Golang’s syntax and read any project; and a few days to start using it in development. In comparison, Rust has a steeper learning curve. It takes a few weeks to start development. The problem with learning Rust is the more tricky syntax – at least at the beginning. Sometimes it can be a case of searching for issues on GitHub. Furthermore, the documentation of Rust is harder to understand when using it for the first time.
As a rule, it is easier for developers to switch from another programming language to Golang than to Rust.
They both have two great tools that standardize and facilitate software development – the format tool and build tool. These tools make projects much more accessible to read and build. If all developers know these tools, it's almost effortless to introduce newcomers to the project and it’s easier to maintain it.
Starting a new project (e.g. in C++) raises the following questions:
- Should we put formatting rules in coding guidelines?
- Should we create a config file for the external formatting tool?
- Should we let developers format the code as they want?
All these questions are resolved by the default formatting tool for both languages.
Rust and Golang resolve issues with inconsistent formatting. Nevertheless, compared to Go, the Rust formatting tool is described as being stricter.
Having ready-to-use solutions speeds up development both at the beginning of the project and for project newcomers.
Rust and Go come with powerful build tools along with dependency management. In a handy file, developers can specify packages and their versions. The dependencies are automatically downloaded and compiled.
This is a real help as modern software relies on numerous packages that facilitate project development.
>> Explore our Rust development services
Programs in both programming languages are compiled, but those written in Rust have better performance. On the other hand, development in Golang and its compiler is much faster – we don’t have to worry about ownership rules because it uses a garbage collector. Of course, it impacts the performance but in some cases development speed is crucial.
Rust is free from undefined behavior issues and has low-cost abstraction – these optimizations and checks make compilation slower.
To sum up – in terms of development speed and shallow learning curve, Golang is the better solution. If you focus on better performance and more predictable memory management, then Rust is the better option.
This is not our first Rust comparison – if you are interested in the Rust vs. C++ battle results, check out the previous article.
As I already mentioned – Rust and Golang are equally great candidates for your next project (if they fulfill the project’s requirements and are properly chosen for the application field). These programming languages have various great features that can make your work more effective and more manageable. I’ve shared my personal and honest opinion about these solutions based on my professional, daily work experiences.
Both Rust and Golang have great tools and features that make development and maintenance simple, fast and reliable. Golang is much easier to learn and faster in terms of development. It’s a lot of fun from the very beginning.
Nevertheless, I would choose Rust over Golang. Apart from the features described above, there are some others, like powerful enums and pattern matching or conditional compilation unit tests, that I really love.
Furthermore, slightly better exception handling and functional programming features like processing a series of items with iterators make development in Rust much more enjoyable. Of course, technology should be chosen according to the project objectives, but from a personal perspective, the feelings linked to development in Rust are more positive.
If you are looking for more arguments to use Rust, you can read one of our previous articles about why the Rust programming language is so popular.
Read our other Rust-related articles