Borrow checker that ensures you won't shoot yourself in the leg like you can with C and C++.
Powerful type system which is much more powerful than what other static typed programming languages can offer (except few exceptions like Haskell). I would quote No Boilerplate's amazing explanation on this - It's not C++, but better. It's Haskell standing on LISP's shoulders, hiding in C's coat to sneak into production.
Everything is immutable by default.
There is no null.
There are no exceptions - every function that can fail returns Result<T, E> and ? operator allows you to easily propagate errors (so you get best of the both worlds). Edit: there is a panic! which is similar to exceptions in it's behavior but it's used for non-recoverable errors only (see my comment below)
Hands down the best official documentation I've ever seen - the book, rustlings (small interactive exercises allowing you to learn how to write idiomatic Rust) and the reference is everything you need to become proficient pretty quick.
rust-analyzer is pretty great and gives you the experience of an IDE in VS Code and other code editors.
The bad
Compile time. Because of the various checks that need to be done, every crate (library in the Rust world) needs to be compiled.
Because of the borrow checker, it's much harder to do some things which are quite easy in other languages (recursive data structures are one of the most notorious examples).
Because of the guarantees borrow checker gives us, asynchronous programming in Rust is much more complicated than in other languages.
It can become very verbose very fast. Check this example which shows how to set up tracing in an Axum web app.
I'm a bit of a Rust newbie, but some of the "good" things seem like semantics. Maybe you can correct my thinking here?
There are no exceptions
The compiler throws a ton of exceptions, Rust is famous for it. And there's panic!, which in my experience is more common than advertised.
There is no null
But there is None, which doesn't seem that different to me. Is there a difference in the way you handle a nullable value in another language (say int?) and the way you handle optional values in Rust (like Option<isize>)?
I agree with your other points. Rust is my favorite language for performance-sensitive scripts, and I'm always happy to see things being rewritten in it.
What I wanted to say is that there are no exceptions in the same sense there are in other languages (like Java, C++ or C# for example). panic! exists but is used for non-recoverable errors (and while technically it is possible to catch a panic with catch_unwind it's not guaranteed you'll be able to do it). Basically, try / catch mechanism has been replaced by introducing error handling by Result.
Returning Result allows you to have information about functions that could fail ingrained into the type system, forcing you to act on it. But I understand that this could lead to confusion for beginners so I'll edit my comment.
None and null are not the same thing. Option<T> type is in fact an enum which could only be Some<T> or None, therefore everything that could be done with other enums could be done with Option<T> - you can match on it and there are several built-in functions like and_then or unwrap_or for more granular control.
null on the other hand basically means null pointer or a pointer that does not point to any valid object. While modern languages like Kotlin do introduce optional types, they won't prevent you from having uninitialized variables, because you need to use String? instead of String to ensure you don't end up having null. In Rust, this is prevented by ensuring every variable must be initialized before it's used. Whether you have an Optional<i32> or i32, you need to initialize it first.
So, while they may seem as the same thing, null and None are not the same.
Keep in mind that things I wrote are focused on the safe Rust. Unsafe Rust, on the other hand, is a different beast and topic for itself; there is for example std::men::MaybeUninit for wrapping possibly uninitialized instances.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Rust
The good
null.Result<T, E>and?operator allows you to easily propagate errors (so you get best of the both worlds). Edit: there is apanic!which is similar to exceptions in it's behavior but it's used for non-recoverable errors only (see my comment below)The bad
I'm a bit of a Rust newbie, but some of the "good" things seem like semantics. Maybe you can correct my thinking here?
The compiler throws a ton of exceptions, Rust is famous for it. And there's
panic!, which in my experience is more common than advertised.But there is
None, which doesn't seem that different to me. Is there a difference in the way you handle a nullable value in another language (sayint?) and the way you handle optional values in Rust (likeOption<isize>)?I agree with your other points. Rust is my favorite language for performance-sensitive scripts, and I'm always happy to see things being rewritten in it.
What I wanted to say is that there are no exceptions in the same sense there are in other languages (like Java, C++ or C# for example).
panic!exists but is used for non-recoverable errors (and while technically it is possible to catch a panic with catch_unwind it's not guaranteed you'll be able to do it). Basically, try / catch mechanism has been replaced by introducing error handling byResult.Returning
Resultallows you to have information about functions that could fail ingrained into the type system, forcing you to act on it. But I understand that this could lead to confusion for beginners so I'll edit my comment.Noneandnullare not the same thing.Option<T>type is in fact an enum which could only beSome<T>orNone, therefore everything that could be done with other enums could be done withOption<T>- you can match on it and there are several built-in functions likeand_thenorunwrap_orfor more granular control.nullon the other hand basically means null pointer or a pointer that does not point to any valid object. While modern languages like Kotlin do introduce optional types, they won't prevent you from having uninitialized variables, because you need to useString?instead ofStringto ensure you don't end up havingnull. In Rust, this is prevented by ensuring every variable must be initialized before it's used. Whether you have anOptional<i32>ori32, you need to initialize it first.So, while they may seem as the same thing,
nullandNoneare not the same.Keep in mind that things I wrote are focused on the safe Rust. Unsafe Rust, on the other hand, is a different beast and topic for itself; there is for example
std::men::MaybeUninitfor wrapping possibly uninitialized instances.