Marco Alka nice article. I too learned Rust recently (last year) and I definitely appreciate its strengths. I haven't used it in a bit though for anything useful because I found that most of the times I am reaching for C, it's because I want to do unsafe things... So reaching for Rust instead just became overburdening for most tasks that I would use C for. I also found some oddities within Rust such as no direct built-in access to raw sockets??? And it's called a systems level language??? Strange.
Also, I found byte-manipulation to be overly cumbersome and involve a bunch of crates... I would expect strong byte manipulation out-of-the-box in a systems-level language.
I would want Rust over C for developing production software because at that point, it's a bigger endeavor anyway, but for quick tools and hacks, I still prefer C for many things like networking and working with bytes. However, I do reach for Rust for threading and working with strings over C for sure.
We'll see how Rust does in the future.
Followed from _this_week_inrust and I liked your post. Some sections were difficult to parse in English, but overall it's inspiring and motivating for a new Rustacean like me ( < 1 month learning)!
One suggestion is to change the divide function to not introduce the concept of 'static which seems kind of distracting for the beginner audience. Here is an alternative:
fn divide(a: i32, b: i32) -> Result<f32, String> {
if b == 0 { return Err(String::from("Cannot divide by 0!")); }
Ok(a as f32 / b as f32)
}
About game development-- I also dabbled in game dev in the past, using Unity3d. You are right to not attempt developing a game engine from scratch. Too much work, you will never finish a game! Just leverage an existing game engine, and try to make a great game, then another and another!
That said, even though it is at version 0.x.x , amethyst looks totally awesome!
Thanks for this great article. It sounds similar to my experience with Rust: I picked it up for a toy project. It was a blast at first, but then, after few days and couple hundreds lines of code, there came lifetime errors I really could not resolve. I tried and tried but finally gave up and put Rust on a shelf labelled "maybe try out again later".
I never did, although for some time I'm starting to think about it. I think you have just encouraged me to do so, as your story is similar, but you managed to fully ovecome the difficulties. Thanks again!
Just to be pedantic, you can delegate on implementations rather than interfaces, right? Just delegate to a struct (which also have methods).
I had some trouble getting used to the borrow checker too. But seeing it is the one big thing people warn about with Rust, it went faster than I thought.
I struggled more with things like object safety and with orphan rules. For some reason they're hard for me to get used to - it just doesn't come up in Java or Python...
The Rust documentation and tools are pure gold.
That doesn't include the IDE support as a tool though :-) I'd be a lot more productive if Rust had the IDE support that Java has. (I use CLion which has okay Rust support, but it's going to take time catching up with the long-established languages).
I also have the problem of wanting to write Rust-style code in other languages.
I didn't like it before either, but now I've really developed an aversion to Java objects being references from multiple places. If there'd just be one owner like in Rust then I could assume the object isn't changed.
Smart people had said before that mutable state is hard to reason about, and I believed it. But I only really understood the benefit when the compiler enforced it.
At first the borrow checker seemed like bookkeeping to prevent GC. But that seriously| underestimates it (and your article rightly mentioned threading protection prominently).
But the problem with threading is that your state is changed between lines. That problem still happens to some extent in a huge single-threaded codebase. Sure I set an object field here, and then use it later, but I'd have to understand all the lines in between, recursively, to know my state didn't change.
Hey, look at this programming language! It's so cool!!!", however when I saw the syntax, my head started spinning and I could only think: "Well, yeah..... no. What an ugly syntax. What a roundabout, complicated way to get things done. I can do the same with modern C++ and have more control at the same time."
Exactly my thoughts now, with just one week being with it. Hope it's gonna change soon, as I am realizing how fast and efficient it is coming from JS(Node) background.
Thanks for sharing such a wonderful article. :)
Nice article!
Now that you have experience, what would be the appropriate way of implementing the following in Rust?
class Object { doSth() { cout >> "Do Something!" >> endl; } } class StaticMesh: public Object { doMeshyThing() { cout >> "Do Meshy Thing!" >> endl; } }I doubt the code you wrote after is the best approach:
trait TObject { fn doSth(&self); } trait TStaticMesh { fn doMeshyThing(&self); } pub struct Object; pub struct StaticMesh; fn doSth<T: TObject>(obj: &T) { println!("Do Something!"); } fn doMeshyThing<T: TStaticMesh>(obj: &T) { println!("Do Meshy Thing!"); } impl TObject for Object { fn doSth(&self) { doSth(self); } } impl TObject for StaticMesh { fn doSth(&self) { doSth(self); } } impl TStaticMesh for StaticMesh { fn doMeshyThing(&self) { doMeshyThing(self); } }And coming from OOP, I'm kind of curious to see the final Rust implementation of those 2 lines of code.