The Rust standard library feels so much more modern and easy to use than the STL. The documentation is fantastic, too.
C++ pointers, casting, OO, templates, and all the billion other language features feel like traversing down a rabbit hole. Rust is small enough to grok in a day. The syntax is incredibly expressive and a joy to use.
I would say it is far easier to learn how to write good systems code in Rust than C++, but saying you can grok it in a day is a bit optimistic. On the surface level, perhaps. But the semantics of the type system can take longer to internalise, depending on one's background.
Don't forget your & in your function declaration or you'll silently copy objects.
Don't forget to make your destructor virtual in your base class (don't forget to add it if the class wasn't originally going to be a base class!) or you get fun crashes on delete every once in a while.
Use "explicit" with your one-parameter constructors to avoid fun with automatic conversions.
std::string is practically useless
Use "." with classes/structs/references and "->" pointers (why am I the compiler?!)
Think you know what "a = b;" does? Think you know what the =,==,!=,<,>,^,,+,-,/,=,+=,-=,/=,^= operators do? Not unless you checked to see if someone override them!
Ever tried to read some code that uses templates?
If you declared Class(int x) and Class(char x) and then do Class('a'), it silently gets constructed with the integer version (or maybe it's with Class(const char x), can't remember, which should say something right there.)
Quick, what does "const int const x;" mean?
Quick, what does "int* a, b;" do, and is that what you expected?
Is it safe to do "a = b"? You don't know until you read through all the class hierarchies to see if the object has a pointer, and if so, if it has an assignment operator that works properly ("properly" being somewhat relative to the purpose of your object).
Fun times debugging stuff like
if (...)
statement1;
statement2;
Can you call a virtual function from a constructor? Which version of C++ are you using?I have a soft spot in my heart for C++, but boy is there a lot to remember, and the mistakes/typos can kill a good half-day, minimum. I'm excited for the day I have a project I can use Rust on, looking forward to something I don't have to be always on my guard with!
> Don't forget your & in your function declaration or you'll silently copy objects.
I think this still exists in Rust to a limited extent but it's mitigated:
* Rust uses move semantics by default, so unless the type was specifically marked as Copy[0] it will be moved into the function which should be noticeable
* references are actual types, `&Foo` can't be confused with `Foo` and (outside of method receivers) references are created explicitly, so the callsite knows whether it's passing a reference
> Don't forget to make your destructor virtual in your base class (don't forget to add it if the class wasn't originally going to be a base class!) or you get fun crashes on delete every once in a while.
Rust has almost no inheritance support, and the realms of static and dynamic dispatches are pretty well separated (trait objects are dynamic, the rest is mostly static) so that should not be an issue.
> Use "explicit" with your one-parameter constructors to avoid fun with automatic conversions.
Rust has very little implicit behaviour (auto-deref is the main one I think), and I don't think it has implicit/automatic conversions.
> std::string is practically useless
Without more information as to its failing, I can't say whether String (and &str) is more useful. IME it certainly is useable and useful.
> Use "." with classes/structs/references and "->" pointers (why am I the compiler?!)
Yup, this is done through auto-defer (of types implementing the relevant trait of course), though it does have a separate `::` for other context.
> Think you know what "a = b;" does? Think you know what the =,==,!=,<,>,^,,+,-,/,=,+=,-=,/=,^= operators do? Not unless you checked to see if someone override them!
Can't override assignment itself, you can override other operators[1] and there is an accepted RFC for overloading augmented assignments[2]. Though these overrides are trait-based which should limit the shenanigan space somewhat.
> Ever tried to read some code that uses templates?
Rust's generics are slightly simpler, but they're lacking features (no template specialisation currently) so… not sure.
> If you declared Class(int x) and Class(char x) and then do Class('a'), it silently gets constructed with the integer version (or maybe it's with Class(const char x), can't remember, which should say something right there.)
See item above, the very declaration doesn't exist in Rust, you'd need to have two separate factory functions.
> Quick, what does "const int const x;" mean?
Should be clearer in rust, type declarations are fairly regular.
> Quick, what does "int* a, b;" do, and is that what you expected?
I think that's equivalent to `int* a; int b`?
Type information is an optional postfix addendum in Rust, so the ambiguity doesn't exist, but if you want explicit types you don't get the convenience of shortened declaration. The closest to this code would be
let (a, b): (Box<u32>, u32)
which isn't much of a gain over let a: Box<u32>;
let b: u32;
if you're not unpacking an existing structure> Is it safe to do "a = b"? You don't know until you read through all the class hierarchies to see if the object has a pointer, and if so, if it has an assignment operator that works properly ("properly" being somewhat relative to the purpose of your object).
See above, assignment itself can't be overloaded (at least at the moment)
> Fun times debugging stuff like
I think the only places where braces are optional in Rust are non-ambiguous 1-expression lambdas (`|| {expr}` can be written as `|| expr`) and 1-expression match arms e.g.
match foo {
v1 => { expr1 },
v2 => { expr2 },
}
can be written match foo {
v1 => expr1,
v2 => expr2,
}
> Can you call a virtual function from a constructor?Rust doesn't have constructors so no. As for the intent, since Rust doesn't have constructors you can't have partially built values (unless you forcefully partially build them) so the answer should still be no.
[0] http://doc.rust-lang.org/std/marker/trait.Copy.html
> I've never done anything with Rust […] I expect they have done away with a whole lot of C++ complexity
and trying to show whether, where and how rust had done so on the various examples provided.
Rust does have a lot of features, but for most programming often you don't have to dabble in the more advanced features, which is great. Whilst working on Servo I mostly stuck to the basic features which I was familiar with for a long time and only learned the complicated stuff after a few months out of interest.
One major difference is that Rust forces you to learn about ownership and borrowing up front. This is cognitive load you would have to take in any systemsy language at some point when learning about memory management, Rust just makes you learn it early.