Skip to content

Advanced

Pages that assume the Foundations spine and then add a second hard thing on top — shared state across threads, unsafe, FFI, macros, layout and performance. Nothing here is harder to read than a Foundations page; what makes it advanced is that the mistakes cost more and the compiler helps less.

Each page is still one idea with a program you can compile and run beside it.

Lesson Level What it teaches
Spawning a thread 201 → 301 spawn, the JoinHandle that is the only way to a return value, the 'static bound behind E0373, and thread::scope — which borrows what spawn cannot, so a fan-out needs no Arc at all
Channels 201 → 301 Handing a value over instead of sharing one: send moves, the Sender you kept that stops the program exiting, the difference between empty and disconnected, and when a bound is backpressure rather than a limit
Lock poisoning 301 Why Mutex::lock() returns a Result at all, what your .unwrap() is deciding on someone's behalf, and the three honest answers
The right to post is a value 301 Authentication as a type rather than a boolean — a permission that cannot be forged, a post that spends it, and the hole move semantics still cannot close
Scale the denominator away 301 Exact arithmetic without fractions — why a float breaks a tied count, why the rationals that fix it cost a gcd apiece, and when you can multiply the denominators out and spend the count in i128
What i128 is exact about 301 The three different properties "exact" gets used for, which one a 128-bit integer actually has, what widening costs per operation — and why fractions.Fraction is a different trade rather than a slower one
When the denominators compound 301 The proportional allocation the companion trick cannot reach — why its denominators compound out of the previous round's, why the width you need is a property of the data, and what a fixed-width rational really runs out of
Did the rounding decide it? 301 The question the other four do not ask — bracket each rounded term instead of storing it, and find out whether your choice of scale or the data picked the answer; sound but not complete, so decided is a proof and undecided is only about that scale
What an invariant is 301 The promise a type carries — established at the one door that can build it and assumed everywhere else, which is why .chars() validates nothing and has no error case to handle; the two clauses of Chars::next's SAFETY comment and why the second follows from the first; and the ordinary kind, where breaking one costs a wrong answer rather than undefined behaviour
What unsafe turns off 301 The five powers it grants and the nothing else it turns off — the borrow checker still runs inside the block; split_at_mut as a safe API over a small unsafe core; unsafe fn vs unsafe {} after edition 2024; and why the audit unit is the module, because a safe line three away is what makes the block sound
Calling C 301 "No overhead FFI" is a claim about the callextern "C" is an ordinary call instruction with no marshalling layer. The data is the bill: a &str carries a length and a C string carries a terminator, so every string that crosses is allocated and copied, and the conversion can fail. Plus edition 2024's unsafe extern and its safe fn, and the unbounded lifetime CStr::from_ptr hands back
What a union is 301 Fields on top of each other instead of side by side — why the write is safe and the read is not, why the field type decides whether a bad read is merely wrong or undefined, and why an enum is this with the tag already checked
Interior mutability 301 Writing through a &TCell and RefCell move the borrow check from compile time to run time, which buys the shapes the static checker cannot prove and costs a panic instead of an error. Stub
Send and Sync 301 The two methodless traits that decide what may cross a thread boundary, why nobody writes either, and why the error always names a type three layers inside the closure. Stub
RwLock and atomics 301 The two rungs either side of a Mutex — and the reason two atomics read together are not atomic together. Stub
The global allocator 301 Where every heap byte comes from — swapping in a counter that turns String's capacity ladder into events you can see, the three rules that keep such a measurement honest, and why the five ways to make a String all cost exactly one allocation
Allocator::shrink 301 The request Vec::shrink_to_fit bottoms out in — the three-way branch behind "may either shrink in-place or reallocate", why shrinking to zero is not a shrink, why the old pointer is dead even when the block never moved, and the provided body that turns giving memory back into the most expensive operation available

Planned

Rough order, not a promise. The three that used to sit here — Send/Sync, RwLock and atomics, and interior mutability — are stubs in the table above now, which is the same list with their boundaries written down. FFI has since left this list for the table: Calling C.

  • Macrosmacro_rules! and the procedural kind, once what the ! means has been said at 101

Po polsku

„Zaawansowany” brzmi po polsku jak zapowiedź trudniejszej składni, i akurat tutaj znaczy coś innego. Żadna z tych stron nie jest trudniejsza w czytaniu niż strony z 01_Foundations — zaawansowane jest to, że błąd kosztuje więcej, a kompilator pomaga mniej. W unsafe nie znika borrow checker (działa dalej, w środku bloku), znika tylko kilka konkretnych gwarancji; przy FFI i przy surowych wskaźnikach to ty bierzesz na siebie dowód, którego dotąd wymagał od ciebie kompilator. Wątki są w tym rozdziale z tego samego powodu: spawn wymusza 'static, thread::scope pozwala pożyczyć zamiast klonować, a Mutex::lock() zwraca Result nie bez przyczyny — twoje .unwrap() podejmuje wtedy decyzję za kogoś innego.

Rozdział ma jeden garb, którego nie znajdziesz w typowym „advanced Rust”: cztery strony pod rząd o dokładności liczenia — skalowanie mianowników, co właściwie jest dokładne w i128, co się dzieje, gdy mianowniki narastają z rundy na rundę, i arytmetyka przedziałowa, która jako jedyna pyta, czy o wyniku nie zdecydowało zaokrąglenie. To nie jest teoria liczb dla ozdoby: liczenie głosów na f64 potrafi rozstrzygnąć remis w złą stronę, a „dokładny” to po polsku, tak samo jak po angielsku, słowo używane na trzy różne sposoby naraz.

Praktyczna uwaga do czytania tabeli: pozycje oznaczone Stub to celowo zapisane granice tematu, a nie gotowe lekcje — po polsku najbliższe będzie „szkic”. I nie szukaj polskich odpowiedników nazw z tej tabeli: Send, Sync, unsafe, union i cała reszta to słowa kluczowe albo nazwy typów, więc odmieniamy je po polsku („w unsafe”, „przez Mutexa”), ale nie tłumaczymy.

Szukaj po polsku: wielowątkowość w Ruscie · arytmetyka dokładna zamiast zmiennoprzecinkowej · rust unsafe what it turns off · rust thread scope borrow · rust mutex poisoning