This is Swift · expert, lesson 1: Sendable and data races. Read the teaching and the stills before the checks. The quizzes are open book and test the subject — Swift itself — not product rules or layout trivia.
Swift Expert · Lesson 1 · On the house
Sendable and data races
Sendable, isolation, why value types help. Lesson 1 is free — on the house.
Lessons · Swift Expert · Lesson 1 of 10 · On the house
Sendable and data races
Sendable, isolation, why value types help.

Expert assumes Introductory through Medium. We go deep — no beginner restarts.
Expert assumes actors and async/await from Medium. The next hardening layer is Sendable: a type that can cross concurrency domains without introducing data races.
Sendable is a marker protocol. Many value types (structs/enums whose stored properties are Sendable) get implicit conformance. Reference types do not — a class must be carefully designed (immutable, internally synchronized, or actor-isolated) before you claim Sendable.
Swift 6 concurrency checking treats non-Sendable values crossing isolation boundaries as errors (or warnings under weaker settings). That is the compiler helping you find races that used to be runtime luck.
Value types help because mutation is on your copy unless you share a reference underneath. A struct Point { var x: Int; var y: Int } crossing a Task boundary copies; two tasks do not silently mutate the same storage.
Classes plus shared mutable fields are the classic race: two tasks write counter.n without isolation. Prefer an actor, a Sendable immutable snapshot, or a dedicated lock type — not hope.
@unchecked Sendable opts out of compiler proof. Use it only when you have a real invariant the type system cannot see (and document why). It is not a style preference.
Misses: marking a mutable class Sendable casually, assuming await alone makes shared class state safe, or treating Sendable as a runtime cast instead of a static contract.
Put Sendable and data races in a sentence you could teach a friend: what changes, what stays the same, and what you expect from the still.
Change one dial at a time when you experiment, then re-run. Batch changes invent ghost bugs.
Predict the still on paper before you type. Prediction turns running into confirmation.
Name each token in the still aloud. Hesitation marks the exact gap.
When something fails, read the last error line first. Calm retries beat rewriting everything.
sendable
struct Score: Sendable {
let value: Int
}
func fanOut(_ s: Score) async -> Int {
async let a = s.value + 1
async let b = s.value + 2
return await a + b
}
Task {
print(await fanOut(Score(value: 10)))
}
print("sendable scheduled")Sit with that still. Trace it top to bottom. Name each piece. The exercise asks you to match its essence.
If something fails when you try it yourself, change one thing. Read the error. Return to the still. I will not rush you.
Quiz
Sendable means?
Quiz
Why do simple structs often help?
Quiz
Swift 6 habit for non-Sendable across isolation?
Quiz
@unchecked Sendable is?
Quiz
Shared mutable class fields without isolation?
Quiz
Preferred Expert move for shared mutability?
Quiz
Does await alone make a mutable class field race-free?
Quiz
Based on today's teaching, which claim is right?
Quiz
Based on today's teaching, which claim is right?
Check
Match the still for: Sendable and data races.
That is the lesson. When every quiz and exercise on this page is green, mark it passed. Next lesson when you are ready.
Open-book: the answers are on this page. Pass every quiz and check (10) to mark the lesson done. This visit: 0/10.