← All topics/Swift language features

Practical interview questions

Scenario-style prompts with sample answer outlines. Focus is on how you would design and reason in real codebases.

Question 9

Sendable, ownership, and mutability

What does Sendable communicate to the compiler? How does it relate to actor isolation and mutability in Swift 6 concurrency?

Answer outline

Sendable marks types whose values can safely cross concurrency boundaries — into actor-isolated contexts, tasks, or concurrent closures, without introducing data races.

Value types whose stored properties are all Sendable conform automatically. Classes must prove safety manually, or use @unchecked Sendable to opt out of compile-time verification.

In Swift 6, passing a non-Sendable value across a concurrency boundary is a compile-time error. The compiler enforces isolation rather than leaving data-race safety to runtime.

Ownership modifiers (borrowing, consuming, inout) and mutating describe how values move between caller and callee — they reinforce value-type safety and exclusive access guarantees.

Sendable conformance paths and how Swift 6 enforces the concurrency boundary at compile time.

Principles

  • Sendable values are safe to cross concurrency boundaries — Swift 6 enforces this at actor call sites and task closures.
  • Structs with Sendable stored properties conform automatically; classes must manually prove thread safety.
  • @unchecked Sendable silences the compiler — you take full responsibility for data-race safety.
  • Prefer immutable types across concurrency boundaries; use actors for shared mutable state.
`borrowing` parameter
func utf8Count(borrowing text: String) -> Int {
    text.utf8.count  // read-only for this call; caller still owns text afterward
}
`consuming` parameter
func logThenDrop(consuming message: String) {
    print(message)
}

logThenDrop(consuming: "done")
`inout` parameter
func double(_ value: inout Int) {
    value *= 2
}

var x = 3
double(&x)
// x is now 6
`mutating` method
struct Counter {
    var n = 0
    mutating func tick() { n += 1 }
}

var c = Counter()
c.tick()  // needs var binding so self can change