Swift optionals interview questions, with answers
Optionals are the first thing that makes Swift feel different from Java, C# or Objective-C: a value that may be missing has a different type from one that cannot be, and the compiler makes you handle the missing case. Every iOS interview asks about them, because careless unwrapping is still the most common way a Swift app crashes.
The answers below cover what an optional is, the safe ways to unwrap one, force unwrapping, optional chaining, transforming optionals, matching them in a switch and why Swift has no null, with code compiled with swiftc 6.4. Then take the free Swift diagnostic — ten questions across every Swift topic in the bank — to see which of these you can explain but not yet predict.
The questions, with answers
1.What is an optional in Swift?
In short: A type such as String? that holds either a value of that type or nil; a plain String can never be nil.
An optional wraps a type to say that a value may be absent. String? holds either a String or nil, while a variable of type String must always contain a string, and the compiler enforces the difference. Before you can use the value inside an optional as its underlying type, you have to unwrap it, which forces the missing case to be handled somewhere. Optionals are used for anything that can legitimately fail or be absent: a lookup that finds nothing, a conversion that fails, or a property that is set later.
var nick: String? = nil print(nick == nil) nick = "Ace" print(nick!.count) // true // 3
2.How do you unwrap an optional safely in Swift?
In short: Use if let or guard let to bind the value when it exists, or ?? to supply a default when it is nil.
if let n = value { } runs its block only when value is not nil, with n bound to the unwrapped value inside the block. guard let n = value else { return } does the reverse: its else branch must leave the scope, and after it n is available unwrapped for the rest of the function, which keeps the main path unindented. Since Swift 5.7 both accept the shorthand if let n and guard let n when the names match, as below. The nil-coalescing operator, value ?? fallback, gives an unwrapped result in one expression.
func greet(_ n: String?) -> String { guard let n else { return "Hi, guest" } return "Hi, \(n)" } print(greet(nil)) print(greet("Ravi")) // Hi, guest // Hi, Ravi
3.What does force unwrapping with ! do in Swift?
In short: value! returns the wrapped value, and if the optional is nil the program stops with a fatal error.
Writing ! after an optional asserts that it contains a value and unwraps it directly. When that assertion is wrong, Swift does not return a default or throw a catchable error: the program stops with the fatal error "Unexpectedly found nil while unwrapping an Optional value", which in an iOS app is a crash. Force unwrapping is reasonable only where nil would be a programming mistake, such as a resource bundled with the app. Everywhere else, use if let, guard let or ?? so the nil case is handled deliberately.
let s: String? = nil let n = s!.count // traps
4.What is optional chaining in Swift?
In short: a?.b?.c reads through optionals and stops at the first nil, making the whole expression nil instead of crashing.
Optional chaining puts ? after an optional value to access its properties, methods or subscripts only when it is not nil. If any link in the chain is nil, evaluation stops there and the whole expression becomes nil, so the result of a chain is always optional, even when the final property is not. In the code, the person has no pet, so o.pet?.name is nil and ?? supplies a fallback. Chaining replaces nested if let statements when you only need to read a value, or call a method, if everything along the way exists.
struct Pet { var name: String } struct Person { var pet: Pet? } let o = Person(pet: nil) print(o.pet?.name ?? "no pet") // no pet
5.What do map and flatMap do on a Swift optional?
In short: map transforms the wrapped value if there is one and keeps nil as nil; flatMap does the same for a transform that itself returns an optional.
Optional has its own map: if the optional holds a value, map applies the closure and wraps the result, and if it is nil, the result is nil without calling the closure. That removes the need to unwrap, transform and re-wrap by hand. When the transform itself returns an optional, such as Int(_:) on a string, map would give a doubly wrapped Int??, so flatMap is used to flatten the result to a single Int?. Both keep the code in one expression, and ?? at the end supplies a default.
let n: Int? = 4 let s: String? = "12" print(n.map { $0 * 2 } ?? 0) print(s.flatMap { Int($0) }!) // 8 // 12
6.How do you match optionals in a Swift switch?
In short: An optional is an enum with cases .some and .none, so a switch can match let x? for a value and nil for absence, with where clauses.
Because Optional is an enum with two cases, some(Wrapped) and none, a switch can match either. The pattern let a? matches when there is a value and binds it, and case nil matches the empty case; a where clause adds a condition, and a later .some catches the values the first pattern rejected. This is useful when the nil case and several value ranges each need different handling, and it keeps all of them in one readable statement instead of nested if let blocks.
let age: Int? = 20 switch age { case let a? where a >= 18: print("adult \(a)") case .some: print("minor") case nil: print("unknown") } // adult 20
7.Why does Swift use optionals instead of null references?
In short: Only optional types can be nil, so the compiler knows which values may be missing and makes you handle them before use.
In languages where any reference can be null, every access is a potential null pointer exception, and nothing in the type says which values might be missing. Swift inverts that: ordinary types can never be nil, so assigning nil to an Int is a compile error, as below, and only an explicit Int? may hold it. The compiler then refuses to let you use an optional as if it had a value until you unwrap it. Missing values are therefore visible in function signatures and handled at compile time, not discovered as crashes.
var count: Int = 0 count = nil // does not compile
How the diagnostic asks it
One question from the Swift bank, exactly as a sitting would show it. The bank has 5 on optionals and 30 across Swift.
What does this Swift code print?
let x: Int? = 5 print(x) print(x!)
- 15, then 5
- 2Optional(5), then Optional(5)
- 3It does not compile: print needs an unwrapped value
- 4Optional(5), then 5correct
x is an Int?, an optional wrapping 5. print accepts Any, so it receives the optional itself and describes it as Optional(5); the compiler warns that the expression is implicitly coerced from Int? to Any, which is a hint that this is rarely intended. x! force-unwraps the value, so the second line prints 5. 5, then 5 assumes print unwraps automatically. Optional(5) twice ignores the !. There is no compile error, only the warning. Use if let, ?? or string interpolation with a default to show optionals.
Measure it
Reading answers tells you what’s true. A diagnostic tells you what you get wrong.
10 Swift questions across its topics, easy to hard, about fifteen minutes. You get a readiness figure with the arithmetic shown, the topics you missed named, and a practice set sized for today. Free: 1 diagnostic a month and 15 problems a day. No card.