Mutate a caller's array in place via an inout parameter
Write removeEvens(from:) that mutates the caller's array in place — removing every even number — through an inout parameter, without returning a new array.
Constraints:
- Mutate the passed array directly; the caller sees the change after the call.
- Do not allocate and return a separate array.
func removeEvens(from numbers: inout [Int]) {
// your code here
}
Then explain in one line why you cannot capture an inout parameter in an escaping closure. Write the implementation.
inout uses copy-in/copy-out — the callee mutates a local copy that is written back to the caller's variable at return, called with &list. You cannot capture it in an escaping closure because the parameter's lifetime ends at return, so a deferred write would hit a dead variable.
- ✗Thinking
inoutpasses by reference like a C pointer rather than copy-in/copy-out - ✗Forgetting the
&prefix at the call site - ✗Believing you can stash an
inoutparameter in an escaping closure for later
- →Why does copy-out happen at return rather than at each write inside the callee?
- →How is an
inoutparameter different from passing aclassinstance?
The solution mutates the array in place; the & at the call site makes copy-in/copy-out explicit:
func removeEvens(from numbers: inout [Int]) {
numbers.removeAll { $0 % 2 == 0 }
}
var list = [1, 2, 3, 4, 5, 6]
removeEvens(from: &list) // list == [1, 3, 5]
inout is not pass-by-reference: the argument is copied in, the function mutates the copy, and at return the value is written back into list. You cannot capture an inout parameter in an escaping closure because the copy-out and the parameter's lifetime both end at return — a deferred write would target a variable that no longer exists.