& borrows a value. * follows a reference to reach the value behind it. The syntax is small, but it sits right in the middle of Rust’s ownership model. If references feel awkward at first, that is normal. In Rust they are not just pointers with nicer spelling. They are part of the language’s safety model.
Many beginner Rust questions are really collection questions in disguise. Most of them come down to four types: String, &str, Vec<T>, and slices like &[T]. These types are connected. If you learn them together, Rust’s API style becomes much easier to read.
Ownership is the idea that makes Rust feel different from most mainstream languages. If this part stays fuzzy, the rest of the language keeps feeling arbitrary. The short version is simple:
Rust does not use null for ordinary absence, and it does not rely on exceptions for recoverable errors. Instead, it uses enums: Option<T> and Result<T, E>. These two types show up everywhere. If you understand them early, a lot of Rust APIs stop looking strange.
Structs and enums are the core of Rust data modeling. Structs group fields together. Enums describe a value that can be one of several well-defined variants. If you are coming from languages where data modeling is mostly “objects everywhere”, Rust feels different at first. It prefers explicit data shapes plus separate behavior.
Rust variables are really bindings. Once that clicks, let, mut, and shadowing stop feeling like syntax trivia and start feeling like design choices. Rust pushes you toward immutability by default. That is not just style. It reduces accidental state changes and makes data flow easier to follow.
Rust functions are explicit at the boundary and flexible inside the body. You spell out parameter and return types, then let inference do most of the local work. That balance is one of Rust’s better design choices. Signatures stay readable, but the code inside them does not turn into annotation noise.
Rust control flow is more than branching and loops. The important part is that many control-flow forms are expressions, which means they produce values. That design shows up everywhere in day-to-day Rust. It makes code concise, but it also forces you to be explicit about the shapes of the values you return.