IteratorProtocol requires next() returning optional = D [OK]
Hint: IteratorProtocol's next() must return optional element type [OK]
Common Mistakes:
Returning non-optional from next()
Confusing Sequence with IteratorProtocol
Missing protocol conformance declaration
3. Consider this Swift code implementing a custom sequence:
struct CountDown: Sequence {
let start: Int
func makeIterator() -> some IteratorProtocol {
var current = start
return AnyIterator {
if current <= 0 { return nil }
defer { current -= 1 }
return current
}
}
}
for number in CountDown(start: 3) {
print(number)
}
What is the output?
medium
A. 3 2 1 0
B. 3 2 1
C. 4 3 2 1
D. 1 2 3
Solution
Step 1: Understand the iterator logic
The iterator starts at start (3). It returns current if > 0, then decreases current by 1 after returning.
Step 2: Trace the iteration values
First call returns 3, then current becomes 2. Next returns 2, current becomes 1. Next returns 1, current becomes 0. Next call returns nil because current is 0, ending iteration.
Final Answer:
3 2 1 -> Option B
Quick Check:
CountDown from 3 to 1 = 3 2 1 [OK]
Hint: Check when next() returns nil to find iteration end [OK]
Common Mistakes:
Including 0 in output though iteration stops before
Assuming count goes up instead of down
Misreading defer behavior
4. This code attempts to create a custom sequence but has an error:
A. next() is a func but modifies count, which is a struct property
B. makeIterator() should return IteratorProtocol instead of MyIterator
C. count should start at 0, not 3
D. next() must return non-optional Int
Solution
Step 1: Identify mutability issue in next()
The next() method tries to change count, but it is declared in a struct and next() is not marked mutating.
Step 2: Understand Swift struct rules
In structs, methods that modify properties must be marked mutating. Without it, the compiler will error.
Final Answer:
next() is a func but modifies count, which is a struct property -> Option A
Quick Check:
Mutating methods must be marked mutating = A [OK]
Hint: Mark methods mutating if they change struct properties [OK]
Common Mistakes:
Forgetting mutating keyword on next()
Thinking return type must be non-optional
Confusing return type with protocol requirement
5. You want to create a custom sequence that iterates over only even numbers from 2 up to a given limit. Which implementation correctly uses the Sequence protocol for this?
hard
A. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 2
return AnyIterator {
while current <= limit {
let result = current
current += 2
return result
}
return nil
}
}
}
B. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 0
return AnyIterator {
current += 2
if current < limit {
return current
}
return nil
}
}
}
C. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 2
return AnyIterator {
if current <= limit {
let result = current
current += 2
return result
}
return nil
}
}
}
D. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 0
return AnyIterator {
if current < limit {
current += 2
return current
}
return nil
}
}
}
Solution
Step 1: Check iterator logic for even numbers
The iterator should start at 2 and return current if <= limit, then add 2 for next call.
Step 2: Analyze each option's iteration behavior
struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 2
return AnyIterator {
while current <= limit {
let result = current
current += 2
return result
}
return nil
}
}
} uses a while loop inside the closure, which causes it to return only once and then exit, so it won't iterate properly. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 2
return AnyIterator {
if current <= limit {
let result = current
current += 2
return result
}
return nil
}
}
} uses an if check and returns current then increments, correctly producing even numbers up to limit. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 0
return AnyIterator {
current += 2
if current < limit {
return current
}
return nil
}
}
} increments before checking, so first returned number is 2, which is correct, but starts at 0 which is okay. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 0
return AnyIterator {
if current < limit {
current += 2
return current
}
return nil
}
}
} increments after checking current < limit, so it may skip the limit if limit is even. struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 2
return AnyIterator {
if current <= limit {
let result = current
current += 2
return result
}
return nil
}
}
} is the clearest and correct implementation.
Final Answer:
struct EvenNumbers: Sequence {
let limit: Int
func makeIterator() -> AnyIterator<Int> {
var current = 2
return AnyIterator {
if current <= limit {
let result = current
current += 2
return result
}
return nil
}
}
} -> Option C
Quick Check:
Use if check and increment after return for correct iteration = B [OK]
Hint: Use if condition inside iterator closure, not while loop [OK]
Common Mistakes:
Using while loop inside iterator closure causing single return
Incrementing before returning causing off-by-one errors
Incorrect start value causing wrong first element
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.