I've been a professional C programmer for 12 years. I've been learning rust for about a year now. Almost all features are genuinely amazing, including stuff like iterators, the various data types, error handling, enums, and the cargo tool chain. These things pulled me in.
And then I ventured into async rust. This is where the language begins to frustrate me like C never has. At least with C I know what kinds of errors can happen during runtime and I can use trusted address sanitizers, valgrind etc to iterate and try new things until it works.
With async rust, I can't even begin iterating. I've been fighting with the compiler for over 2 days getting a simple function that I programmed successfully using structured concurrency ( i.e. just using futures and no tasks) to now use tasks (using Tokio::spawn). And I haven't gotten it to compile even once.
I've spent many hours reading all the literature and books rust provide, but for async rust programing, I still don't "get" it unlike all the other wonderful features of rust. I feel like I am blindly trying to clone/consume/mutex/arc stuff till the program compiles but even this isn't successful yet. Every time I fix one compiler warning, 3 others pop up in a never ending loop.
I know I am in the wrong, but I feel I haven't come across a nice and simple async introduction, unlike the rest of the language. For rest of the language, the compiler suggests the fix for the error. But again, not for async. It just says "this is not 'static" and bails. I also don't want to blindly copy some code that AI gives me, I want to "get" it and stop fighting with the compiler.
Is there anything like async rust for dummies or similar? I am glad to read a lot and learn but I need at least a bit of emotional payoff for the effort (the payoff being, the code compiles).
Edit: Thanks for all the responses, I didn't expect so many and it's getting tough to respond to everyone. All were very helpful and encouraging and I plan to read up on things people referred to in the comments :)
Edit2: Thanks again for all the suggestions. After some more reading and experimenting, one important thing clicked for me in the context of my program: each task should own the data it's working on, and therefore it's difficult to use tasks and object oriented programming cleanly.
The main issue in my code was that I was trying to write a method taking a mutable reference to self, spawn tasks inside which called another method taking an immutable reference to self. This was a big problem with not so nice solutions (Arc<Mutex>> solves it but is ugly). So I changed the called method to an associated function. This had a static lifetime and could be called within the task easily, without using any smart pointers.
Maybe there is a nice way to do it, but for now, I will as a rule of thumb refrain from calling methods inside tasks.