Rust is considered by many to be one of the hardest mainstream programming languages. Many beginners struggle a lot when learning rust, despite the excellent tooling, decent standard library, and painless package management. That means there is something inherently difficult/tricky about the core language itself that newcomers find very difficult to come to terms with.
Rust is a huge language and it's increasing in size everyday. It has a lot of complicated features like generics, metaprogramming, build scripts etcetra. In this article, I'm going to focus only on the borrow checker and the type system, since these are the first core features of the language to trip up newcomers.
Take a look at this function:
It reads a file, splits it into lines, skips the first line, processes the rest of the lines, and calls a finalizer if all the processing operations succeeded. These are some of the noteworthy things about this code:
There are exactly three type annotations in this function, all in the function signature. The compiler infers everything else on its own.
A lot of objects are being created in this function. Some of them own resources (
read_to_string()). Others hold references to resource owners ( line_iter). The compilers (specifically, the borrow checker), ensures that all the resources are freed correctly and verifies that all the references are used only within the lifetime of the owner. All of that happens automagically from the point of view of the programmer. This is RAII on steroids.
So newcomers find rust difficult because of how marvellous and helpful the borrow checker is. It tricks newcomers into thinking that rust is a high level language.
Rust is not a high level language. It is a low level language without a garbage collector.