6 ms·
> But at some point in Rust, and it may come soon, you'll encounter a higher step and if you don't fight it with concentration and dedication, you risk not over
by bko 5y ago
> But at some point in Rust, and it may come soon, you'll encounter a higher step and if you don't fight it with concentration and dedication, you risk not overcome it.
Can any rustaceans give me an example of a "higher step" in rust would be?
- dystroy 5y agoAt some point, maybe not immediately, depending on what you're building, you'll have the borrow checker tell you that no, you can't borrow there, or that some construct that you feel safe isn't possible. And it will probably come with a big lot of such errors and you'll have to look for another design pattern. Until it clicks and starts to be natural, there might be a quite rough period. Until you know the essential traits, how to find them, and you're used to clauses on generics, you may also have some difficulties making sense of some generic code or making your own generic code work.
- ithkuil 5y agoI've passed that hill behind me and I rarely have to fight the borrow checker. If you're familiar with the ownership model and learn the few scoping quirks that's not that hard. What I find way harder to cope with is the gazillions of type parameters with gazillions of guards, send, sync, clone or not clone, then impl Foo for Bar vs impl Foo for Arc<Bar> etc etc; and tons of features in cargo crates, also in private workspace projects, .... And the compiler slowness oh man the compiler slowness. EDIT: my life improved a bit since I learned about the cargo hakari plugin
- stouset 5y agoTo expand on this, I think one of the biggest challenges of Rust right now is that the borrow checker and compiler enforce constraints at a "tree"-level that are indicative of "forest"-level design issues with your code. Once you learn to construct forests in a way that harmonizes well with these constraints, you'll very rarely run into these kinds of tree-level issues. But there needs to be more in the way of education that helps you understand the types of designs that the compiler is trying to push you towards. You can generally get past things by simply `.unwrap()`ing and `.clone()`ing your way past compiler issues, but reaching for them too often prevents you from ever learning those (important) lessons given the current lack of better alternatives to learning them.
- bko 5y agoFrom the article: > So before you dive, have an overview of the book (or books). Maybe don't read it fully, but make sure to have read all titles so that you know when to come back to it later. Could someone familiar with Solana smart contract development highlight which titles from 'the book' are most relevant? I imagine developing smart contracts is much more scoped down than most rust projects.
- porknubbins 5y agoFrom having attempted to understand Solana contracts they make heavy use of traits and serialization libraries.
- jph 5y agoSome steps that newcomers ask me about involve memory management, the borrow checker, and sharing data, such as Rc, Arc, dyn, cell. https://doc.rust-lang.org/std/rc/struct.Rc.html https://doc.rust-lang.org/std/rc/struct.Rc.html https://doc.rust-lang.org/rust-by-example/std/arc.html https://doc.rust-lang.org/rust-by-example/std/arc.html https://doc.rust-lang.org/std/keyword.dyn.html https://doc.rust-lang.org/std/keyword.dyn.html https://doc.rust-lang.org/std/cell/ https://doc.rust-lang.org/std/cell/
- ridiculous_fish 5y agoI sheepishly admit to repeatedly trying and failing to overcome modules.
- duped 5y agoHere's a case I ran into. I have a `Span` type and it can act like `RangeInclusive`. I want to index into a `&str` with it. This looks something like this : use std::ops::Index; pub struct Span { start:usize, end:usize, } impl<'a> Index<Span> for &'a str { type Output = str; fn index(&self, span:Span) -> &Self::Output { &self[span.start..=span.end] } } (NB4 RangeInclusive, in this example, Span is almost identical to RangeInclusive, in practice it was not) Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=70e409cb51af1a267e3367f375fa2543 https://play.rust-lang.org/?version=stable&mode=debug&editio... This gives you a cryptic error : error[E0308]: mismatched types --> src/lib.rs:10:19 | 10 | &self[span.start..=span.end] | ^^^^^^^^^^^^^^^^^^^^^ expected struct `Span`, found struct `RangeInclusive` | = note: expected struct `Span` found struct `RangeInclusive<usize>` For more information about this error, try `rustc --explain E0308 This is weird, because you can definitely index into a `&str` with `RangeInclusive`. What you actually need to do is implement it for `str` instead of `&'a str`. This is a little peculiarity with how the `str` type works (to date, this is the only time I've ever needed the raw `str` type and not &str! it almost never is required) and the generic implementation for Index<I> for str combined with how Deref works. It's a small one line change to fix the code, but it's not obvious from the error message how to do it, and a bit tricky to solve unless you knew a little bit more about how Rust's operators get parsed/implemented. In my experience this is a common class of problems when you deal with generic and trait programming in Rust. It's ultimately the front end to an advanced constraint solver, and due to the explosion of complexity when you start making generic things more/less generic you will hit the wall with weirdness and need to understand more about the type system rather than letting the type system prevent you from doing stupid things. Frankly the memory management issue is not a problem once you buy into ownership.